-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Sparc: Add 64-bit feature #157445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sparc: Add 64-bit feature #157445
Conversation
Add a 64-bit feature so a subtarget feature check can tell the pointer size, for future use with HwMode. This is kind of a hack, but this is closer to what other targets do. To use HwModes, there needs to be a subtarget feature. Every other target kludges the module level properties into a subtarget feature for use here, which requires pre/post processing the subtarget features. The APIs for this aren't great. I tried doing something different, closer to what hexagon does, rather than what x86 does to see if it was any nicer. It almost is, except for some reason we don't have an ABI to directly set a bit in the FeatureBitset. Also the test coverage for the different ABI options isn't great. e.g. v9 as a feature almost works, except a single test breaks that uses a sparc32 triple with an explicit v9 feature.
@llvm/pr-subscribers-backend-sparc Author: Matt Arsenault (arsenm) ChangesAdd a 64-bit feature so a subtarget feature check can tell the This is kind of a hack, but this is closer to what other targets do. Also the test coverage for the different ABI options isn't great. Full diff: https://github.com/llvm/llvm-project/pull/157445.diff 5 Files Affected:
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
index fa07578e512b5..9fa60ee5229ba 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
@@ -81,8 +81,16 @@ static MCRegisterInfo *createSparcMCRegisterInfo(const Triple &TT) {
static MCSubtargetInfo *
createSparcMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
if (CPU.empty())
- CPU = (TT.getArch() == Triple::sparcv9) ? "v9" : "v8";
- return createSparcMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
+ CPU = TT.getArch() == Triple::sparcv9 ? "v9" : "v8";
+
+ MCSubtargetInfo *STI =
+ createSparcMCSubtargetInfoImpl(TT, CPU, /*TuneCPU=*/CPU, FS);
+ if (TT.isSPARC64() && !STI->hasFeature(Sparc::Feature64Bit)) {
+ FeatureBitset Features = STI->getFeatureBits();
+ STI->setFeatureBits(Features.set(Sparc::Feature64Bit));
+ }
+
+ return STI;
}
static MCTargetStreamer *
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
index a7b0538d683b6..b523366e6adaa 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
@@ -28,6 +28,7 @@ class MCRegisterInfo;
class MCSubtargetInfo;
class MCTargetOptions;
class Target;
+class Triple;
MCCodeEmitter *createSparcMCCodeEmitter(const MCInstrInfo &MCII,
MCContext &Ctx);
diff --git a/llvm/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td
index cee671e349510..7137e5fbff4ff 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 Feature64Bit : SubtargetFeature<"64bit", "Is64Bit", "true",
+ "Enable 64-bit mode", [FeatureV9]>;
+
def FeatureV8Plus
: SubtargetFeature<"v8plus", "IsV8Plus", "true",
"Enable V8+ mode, allowing use of 64-bit V9 instructions in 32-bit code">;
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
index f2721ead00697..005930834a0c3 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.cpp
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
@@ -28,10 +28,11 @@ void SparcSubtarget::anchor() { }
SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(
StringRef CPU, StringRef TuneCPU, StringRef FS) {
+ const Triple &TT = getTargetTriple();
// Determine default and user specified characteristics
std::string CPUName = std::string(CPU);
if (CPUName.empty())
- CPUName = getTargetTriple().isSPARC64() ? "v9" : "v8";
+ CPUName = TT.isSPARC64() ? "v9" : "v8";
if (TuneCPU.empty())
TuneCPU = CPUName;
@@ -39,6 +40,12 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(
// Parse features string.
ParseSubtargetFeatures(CPUName, TuneCPU, FS);
+ if (!Is64Bit && TT.isSPARC64()) {
+ FeatureBitset Features = getFeatureBits();
+ setFeatureBits(Features.set(Sparc::Feature64Bit));
+ Is64Bit = true;
+ }
+
// Popc is a v9-only instruction.
if (!IsV9)
UsePopc = false;
@@ -50,7 +57,6 @@ SparcSubtarget::SparcSubtarget(const StringRef &CPU, const StringRef &TuneCPU,
const StringRef &FS, const TargetMachine &TM)
: SparcGenSubtargetInfo(TM.getTargetTriple(), CPU, TuneCPU, FS),
ReserveRegister(TM.getMCRegisterInfo()->getNumRegs()),
- Is64Bit(TM.getTargetTriple().isSPARC64()),
InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
TLInfo(TM, *this), FrameLowering(*this) {
TSInfo = std::make_unique<SparcSelectionDAGInfo>();
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.h b/llvm/lib/Target/Sparc/SparcSubtarget.h
index f98aef012a867..b1decca0a4f07 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.h
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.h
@@ -36,8 +36,6 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
virtual void anchor();
- const bool Is64Bit;
-
#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
bool ATTRIBUTE = DEFAULT;
#include "SparcGenSubtargetInfo.inc"
@@ -79,8 +77,6 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
StringRef TuneCPU,
StringRef FS);
- bool is64Bit() const { return Is64Bit; }
-
/// The 64-bit ABI uses biased stack and frame pointers, so the stack frame
/// of the current function is the area from [%sp+BIAS] to [%fp+BIAS].
int64_t getStackPointerBias() const {
|
ABI -> API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable.
And yes, a 32-bit sparc target with a v9 cpu is nearly untested -- which is not too surprising since last I knew it was also not fully implemented.
"Enable SPARC-V9 instructions">; | ||
def Feature64Bit : SubtargetFeature<"64bit", "Is64Bit", "true", | ||
"Enable 64-bit mode", [FeatureV9]>; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is64Bit
predicate in SparcInstrInfo.td
should be changed to use this feature.
Add a 64-bit feature so a subtarget feature check can tell the
pointer size, for future use with HwMode.
This is kind of a hack, but this is closer to what other targets do.
To use HwModes, there needs to be a subtarget feature. Every other
target kludges the module level properties into a subtarget feature
for use here, which requires pre/post processing the subtarget features.
The APIs for this aren't great. I tried doing something different,
closer to what hexagon does, rather than what x86 does to see if it
was any nicer. It almost is, except for some reason we don't have an
API to directly set a bit in the FeatureBitset.
Also the test coverage for the different ABI options isn't great.
e.g. v9 as a feature almost works, except a single test breaks
that uses a sparc32 triple with an explicit v9 feature.