summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKoakuma <koachan@protonmail.com>2024-01-06 19:47:07 +0700
committerKoakuma <koachan@protonmail.com>2024-01-06 19:47:07 +0700
commitfe29e4f003c69409f9bc4c39bbabbcf721448316 (patch)
tree9b62aebc0ef839e0b9d798951bd034cddc8e0d22
parent5237193b87721134541f228e28edfd544a9c8ac8 (diff)
parentd04b31491feebc5d13b071af099ae7263d7a18a8 (diff)
[𝘀𝗽𝗿] initial version
Created using spr 1.3.4
-rw-r--r--clang/include/clang/Driver/Options.td2
-rw-r--r--llvm/lib/Target/Sparc/Sparc.td18
-rw-r--r--llvm/lib/Target/Sparc/SparcAsmPrinter.cpp21
-rw-r--r--llvm/lib/Target/Sparc/SparcSubtarget.cpp15
-rw-r--r--llvm/lib/Target/Sparc/SparcSubtarget.h7
-rw-r--r--llvm/lib/Target/Sparc/SparcTargetMachine.cpp7
-rw-r--r--llvm/test/CodeGen/SPARC/tune-getpcx.ll18
7 files changed, 72 insertions, 16 deletions
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index df12ba8fbcb2..070373b6b88c 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5119,7 +5119,7 @@ def module_file_info : Flag<["-"], "module-file-info">, Flags<[]>,
HelpText<"Provide information about a particular module file">;
def mthumb : Flag<["-"], "mthumb">, Group<m_Group>;
def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>,
- HelpText<"Only supported on AArch64, PowerPC, RISC-V, SystemZ, and X86">;
+ HelpText<"Only supported on AArch64, PowerPC, RISC-V, SPARC, SystemZ, and X86">;
def multi__module : Flag<["-"], "multi_module">;
def multiply__defined__unused : Separate<["-"], "multiply_defined_unused">;
def multiply__defined : Separate<["-"], "multiply_defined">;
diff --git a/llvm/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td
index 1a71cfed3128..7b1033956524 100644
--- a/llvm/lib/Target/Sparc/Sparc.td
+++ b/llvm/lib/Target/Sparc/Sparc.td
@@ -62,6 +62,13 @@ def UsePopc : SubtargetFeature<"popc", "UsePopc", "true",
def FeatureSoftFloat : SubtargetFeature<"soft-float", "UseSoftFloat", "true",
"Use software emulation for floating point">;
+//===----------------------------------------------------------------------===//
+// SPARC Subtarget tuning features.
+//
+
+def TuneSlowRDPC : SubtargetFeature<"slow-rdpc", "HasSlowRDPC", "true",
+ "rd %pc, %XX is slow", [FeatureV9]>;
+
//==== Features added predmoninantly for LEON subtarget support
include "LeonFeatures.td"
@@ -89,8 +96,9 @@ def SparcAsmParserVariant : AsmParserVariant {
// SPARC processors supported.
//===----------------------------------------------------------------------===//
-class Proc<string Name, list<SubtargetFeature> Features>
- : Processor<Name, NoItineraries, Features>;
+class Proc<string Name, list<SubtargetFeature> Features,
+ list<SubtargetFeature> TuneFeatures = []>
+ : Processor<Name, NoItineraries, Features, TuneFeatures>;
def : Proc<"generic", []>;
def : Proc<"v7", [FeatureSoftMulDiv, FeatureNoFSMULD]>;
@@ -118,9 +126,11 @@ def : Proc<"ma2480", [FeatureLeon, LeonCASA]>;
def : Proc<"ma2485", [FeatureLeon, LeonCASA]>;
def : Proc<"ma2x8x", [FeatureLeon, LeonCASA]>;
def : Proc<"v9", [FeatureV9]>;
-def : Proc<"ultrasparc", [FeatureV9, FeatureV8Deprecated, FeatureVIS]>;
+def : Proc<"ultrasparc", [FeatureV9, FeatureV8Deprecated, FeatureVIS],
+ [TuneSlowRDPC]>;
def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated, FeatureVIS,
- FeatureVIS2]>;
+ FeatureVIS2],
+ [TuneSlowRDPC]>;
def : Proc<"niagara", [FeatureV9, FeatureV8Deprecated, FeatureVIS,
FeatureVIS2]>;
def : Proc<"niagara2", [FeatureV9, FeatureV8Deprecated, UsePopc,
diff --git a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp
index cca624e09267..97abf10b1854 100644
--- a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp
+++ b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp
@@ -13,6 +13,7 @@
#include "MCTargetDesc/SparcInstPrinter.h"
#include "MCTargetDesc/SparcMCExpr.h"
+#include "MCTargetDesc/SparcMCTargetDesc.h"
#include "MCTargetDesc/SparcTargetStreamer.h"
#include "Sparc.h"
#include "SparcInstrInfo.h"
@@ -111,6 +112,15 @@ static void EmitCall(MCStreamer &OutStreamer,
OutStreamer.emitInstruction(CallInst, STI);
}
+static void EmitRDPC(MCStreamer &OutStreamer, MCOperand &RD,
+ const MCSubtargetInfo &STI) {
+ MCInst RDPCInst;
+ RDPCInst.setOpcode(SP::RDASR);
+ RDPCInst.addOperand(RD);
+ RDPCInst.addOperand(MCOperand::createReg(SP::ASR5));
+ OutStreamer.emitInstruction(RDPCInst, STI);
+}
+
static void EmitSETHI(MCStreamer &OutStreamer,
MCOperand &Imm, MCOperand &RD,
const MCSubtargetInfo &STI)
@@ -234,8 +244,15 @@ void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
// add <MO>, %o7, <MO>
OutStreamer->emitLabel(StartLabel);
- MCOperand Callee = createPCXCallOP(EndLabel, OutContext);
- EmitCall(*OutStreamer, Callee, STI);
+ if (!STI.getTargetTriple().isSPARC64() ||
+ STI.hasFeature(Sparc::TuneSlowRDPC)) {
+ MCOperand Callee = createPCXCallOP(EndLabel, OutContext);
+ EmitCall(*OutStreamer, Callee, STI);
+ } else {
+ // TODO make it possible to store PC in other registers
+ // so that leaf function optimization becomes possible.
+ EmitRDPC(*OutStreamer, RegO7, STI);
+ }
OutStreamer->emitLabel(SethiLabel);
MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC22,
GOTLabel, StartLabel, SethiLabel,
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
index 81c2137ea730..a5d196c502cd 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.cpp
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
@@ -25,15 +25,18 @@ using namespace llvm;
void SparcSubtarget::anchor() { }
-SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(StringRef CPU,
- StringRef FS) {
+SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(
+ StringRef CPU, StringRef TuneCPU, StringRef FS) {
// Determine default and user specified characteristics
std::string CPUName = std::string(CPU);
if (CPUName.empty())
CPUName = (Is64Bit) ? "v9" : "v8";
+ if (TuneCPU.empty())
+ TuneCPU = CPUName;
+
// Parse features string.
- ParseSubtargetFeatures(CPUName, /*TuneCPU*/ CPUName, FS);
+ ParseSubtargetFeatures(CPUName, TuneCPU, FS);
// Popc is a v9-only instruction.
if (!IsV9)
@@ -43,10 +46,12 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(StringRef CPU,
}
SparcSubtarget::SparcSubtarget(const Triple &TT, const std::string &CPU,
+ const std::string &TuneCPU,
const std::string &FS, const TargetMachine &TM,
bool is64Bit)
- : SparcGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), TargetTriple(TT),
- Is64Bit(is64Bit), InstrInfo(initializeSubtargetDependencies(CPU, FS)),
+ : SparcGenSubtargetInfo(TT, CPU, TuneCPU, FS), TargetTriple(TT),
+ Is64Bit(is64Bit),
+ InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
TLInfo(TM, *this), FrameLowering(*this) {}
int SparcSubtarget::getAdjustedFrameSize(int frameSize) const {
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.h b/llvm/lib/Target/Sparc/SparcSubtarget.h
index 8e3d05d5d7e5..4363942c0d62 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.h
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.h
@@ -45,7 +45,8 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
public:
SparcSubtarget(const Triple &TT, const std::string &CPU,
- const std::string &FS, const TargetMachine &TM, bool is64bit);
+ const std::string &TuneCPU, const std::string &FS,
+ const TargetMachine &TM, bool is64bit);
const SparcInstrInfo *getInstrInfo() const override { return &InstrInfo; }
const TargetFrameLowering *getFrameLowering() const override {
@@ -70,7 +71,9 @@ public:
/// ParseSubtargetFeatures - Parses features string setting specified
/// subtarget options. Definition of function is auto generated by tblgen.
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
- SparcSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
+ SparcSubtarget &initializeSubtargetDependencies(StringRef CPU,
+ StringRef TuneCPU,
+ StringRef FS);
bool is64Bit() const { return Is64Bit; }
diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
index dbc26636e39f..ae7bbcecc6c7 100644
--- a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
+++ b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
@@ -116,10 +116,13 @@ SparcTargetMachine::~SparcTargetMachine() = default;
const SparcSubtarget *
SparcTargetMachine::getSubtargetImpl(const Function &F) const {
Attribute CPUAttr = F.getFnAttribute("target-cpu");
+ Attribute TuneAttr = F.getFnAttribute("tune-cpu");
Attribute FSAttr = F.getFnAttribute("target-features");
std::string CPU =
CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
+ std::string TuneCPU =
+ TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
std::string FS =
FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
@@ -137,8 +140,8 @@ SparcTargetMachine::getSubtargetImpl(const Function &F) const {
// creation will depend on the TM and the code generation flags on the
// function that reside in TargetOptions.
resetTargetOptions(F);
- I = std::make_unique<SparcSubtarget>(TargetTriple, CPU, FS, *this,
- this->is64Bit);
+ I = std::make_unique<SparcSubtarget>(TargetTriple, CPU, TuneCPU, FS, *this,
+ this->is64Bit);
}
return I.get();
}
diff --git a/llvm/test/CodeGen/SPARC/tune-getpcx.ll b/llvm/test/CodeGen/SPARC/tune-getpcx.ll
new file mode 100644
index 000000000000..7454fea0e38d
--- /dev/null
+++ b/llvm/test/CodeGen/SPARC/tune-getpcx.ll
@@ -0,0 +1,18 @@
+; RUN: llc < %s -relocation-model=pic -mtriple=sparc | FileCheck --check-prefix=CALL %s
+; RUN: llc < %s -relocation-model=pic -mtriple=sparcv9 -mcpu=ultrasparc | FileCheck --check-prefix=CALL %s
+; RUN: llc < %s -relocation-model=pic -mtriple=sparcv9 | FileCheck --check-prefix=RDPC %s
+
+;; SPARC32 and SPARC64 for classic UltraSPARCs implement GETPCX
+;; with a fake `call`.
+;; All other SPARC64 targets implement it with `rd %pc, %o7`.
+
+@value = external global i32
+
+; CALL: call
+; CALL-NOT: rd %pc
+; RDPC: rd %pc
+; RDPC-not: call
+define i32 @test() {
+ %1 = load i32, i32* @value
+ ret i32 %1
+}