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(); 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 {