Skip to content

Commit d219467

Browse files
authored
Sparc: Add 64-bit feature (llvm#157445)
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.
1 parent 344708c commit d219467

File tree

5 files changed

+22
-8
lines changed

5 files changed

+22
-8
lines changed

llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,16 @@ static MCRegisterInfo *createSparcMCRegisterInfo(const Triple &TT) {
8181
static MCSubtargetInfo *
8282
createSparcMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
8383
if (CPU.empty())
84-
CPU = (TT.getArch() == Triple::sparcv9) ? "v9" : "v8";
85-
return createSparcMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
84+
CPU = TT.getArch() == Triple::sparcv9 ? "v9" : "v8";
85+
86+
MCSubtargetInfo *STI =
87+
createSparcMCSubtargetInfoImpl(TT, CPU, /*TuneCPU=*/CPU, FS);
88+
if (TT.isSPARC64() && !STI->hasFeature(Sparc::Feature64Bit)) {
89+
FeatureBitset Features = STI->getFeatureBits();
90+
STI->setFeatureBits(Features.set(Sparc::Feature64Bit));
91+
}
92+
93+
return STI;
8694
}
8795

8896
static MCTargetStreamer *

llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class MCRegisterInfo;
2828
class MCSubtargetInfo;
2929
class MCTargetOptions;
3030
class Target;
31+
class Triple;
3132

3233
MCCodeEmitter *createSparcMCCodeEmitter(const MCInstrInfo &MCII,
3334
MCContext &Ctx);

llvm/lib/Target/Sparc/Sparc.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ def FeatureNoFMULS
3434
def FeatureV9
3535
: SubtargetFeature<"v9", "IsV9", "true",
3636
"Enable SPARC-V9 instructions">;
37+
def Feature64Bit : SubtargetFeature<"64bit", "Is64Bit", "true",
38+
"Enable 64-bit mode", [FeatureV9]>;
39+
3740
def FeatureV8Plus
3841
: SubtargetFeature<"v8plus", "IsV8Plus", "true",
3942
"Enable V8+ mode, allowing use of 64-bit V9 instructions in 32-bit code">;

llvm/lib/Target/Sparc/SparcSubtarget.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,24 @@ void SparcSubtarget::anchor() { }
2828

2929
SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(
3030
StringRef CPU, StringRef TuneCPU, StringRef FS) {
31+
const Triple &TT = getTargetTriple();
3132
// Determine default and user specified characteristics
3233
std::string CPUName = std::string(CPU);
3334
if (CPUName.empty())
34-
CPUName = getTargetTriple().isSPARC64() ? "v9" : "v8";
35+
CPUName = TT.isSPARC64() ? "v9" : "v8";
3536

3637
if (TuneCPU.empty())
3738
TuneCPU = CPUName;
3839

3940
// Parse features string.
4041
ParseSubtargetFeatures(CPUName, TuneCPU, FS);
4142

43+
if (!Is64Bit && TT.isSPARC64()) {
44+
FeatureBitset Features = getFeatureBits();
45+
setFeatureBits(Features.set(Sparc::Feature64Bit));
46+
Is64Bit = true;
47+
}
48+
4249
// Popc is a v9-only instruction.
4350
if (!IsV9)
4451
UsePopc = false;
@@ -50,7 +57,6 @@ SparcSubtarget::SparcSubtarget(const StringRef &CPU, const StringRef &TuneCPU,
5057
const StringRef &FS, const TargetMachine &TM)
5158
: SparcGenSubtargetInfo(TM.getTargetTriple(), CPU, TuneCPU, FS),
5259
ReserveRegister(TM.getMCRegisterInfo()->getNumRegs()),
53-
Is64Bit(TM.getTargetTriple().isSPARC64()),
5460
InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
5561
TLInfo(TM, *this), FrameLowering(*this) {
5662
TSInfo = std::make_unique<SparcSelectionDAGInfo>();

llvm/lib/Target/Sparc/SparcSubtarget.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
3636

3737
virtual void anchor();
3838

39-
const bool Is64Bit;
40-
4139
#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
4240
bool ATTRIBUTE = DEFAULT;
4341
#include "SparcGenSubtargetInfo.inc"
@@ -79,8 +77,6 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
7977
StringRef TuneCPU,
8078
StringRef FS);
8179

82-
bool is64Bit() const { return Is64Bit; }
83-
8480
/// The 64-bit ABI uses biased stack and frame pointers, so the stack frame
8581
/// of the current function is the area from [%sp+BIAS] to [%fp+BIAS].
8682
int64_t getStackPointerBias() const {

0 commit comments

Comments
 (0)