summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Sparc
diff options
context:
space:
mode:
authorChris Dewhurst <chris.dewhurst@lero.ie>2016-05-18 09:14:13 +0000
committerChris Dewhurst <chris.dewhurst@lero.ie>2016-05-18 09:14:13 +0000
commit68388a0a9988ee4ec762a1605f3884709391345b (patch)
treebd2a02a3020efb8554b4bc50228ff1a0230a057c /llvm/lib/Target/Sparc
parenta7547183ecb79e71ac5290dd787260d905a1d334 (diff)
downloadbcm5719-llvm-68388a0a9988ee4ec762a1605f3884709391345b.tar.gz
bcm5719-llvm-68388a0a9988ee4ec762a1605f3884709391345b.zip
[Sparc] Add Soft Float support
This change adds support for software floating point operations for Sparc targets. This is the first in a set of patches to enable software floating point on Sparc. The next patch will enable the option to be used with Clang. Differential Revision: http://reviews.llvm.org/D19265 llvm-svn: 269892
Diffstat (limited to 'llvm/lib/Target/Sparc')
-rw-r--r--llvm/lib/Target/Sparc/Sparc.td3
-rw-r--r--llvm/lib/Target/Sparc/SparcISelLowering.cpp16
-rw-r--r--llvm/lib/Target/Sparc/SparcISelLowering.h4
-rw-r--r--llvm/lib/Target/Sparc/SparcSubtarget.cpp1
-rw-r--r--llvm/lib/Target/Sparc/SparcSubtarget.h2
-rw-r--r--llvm/lib/Target/Sparc/SparcTargetMachine.cpp38
-rw-r--r--llvm/lib/Target/Sparc/SparcTargetMachine.h7
7 files changed, 59 insertions, 12 deletions
diff --git a/llvm/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td
index 6193e97c010..51e0b9acdb0 100644
--- a/llvm/lib/Target/Sparc/Sparc.td
+++ b/llvm/lib/Target/Sparc/Sparc.td
@@ -46,6 +46,9 @@ def FeatureHardQuad
def UsePopc : SubtargetFeature<"popc", "UsePopc", "true",
"Use the popc (population count) instruction">;
+def FeatureSoftFloat : SubtargetFeature<"soft-float", "UseSoftFloat", "true",
+ "Use software emulation for floating point">;
+
//==== Features added predmoninantly for LEON subtarget support
include "LeonFeatures.td"
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index 2c21c0bc2e4..1787240df91 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -1463,9 +1463,11 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
// Set up the register classes.
addRegisterClass(MVT::i32, &SP::IntRegsRegClass);
- addRegisterClass(MVT::f32, &SP::FPRegsRegClass);
- addRegisterClass(MVT::f64, &SP::DFPRegsRegClass);
- addRegisterClass(MVT::f128, &SP::QFPRegsRegClass);
+ if (!Subtarget->useSoftFloat()) {
+ addRegisterClass(MVT::f32, &SP::FPRegsRegClass);
+ addRegisterClass(MVT::f64, &SP::DFPRegsRegClass);
+ addRegisterClass(MVT::f128, &SP::QFPRegsRegClass);
+ }
if (Subtarget->is64Bit()) {
addRegisterClass(MVT::i64, &SP::I64RegsRegClass);
} else {
@@ -1760,7 +1762,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FP_ROUND, MVT::f32, Custom);
// Setup Runtime library names.
- if (Subtarget->is64Bit()) {
+ if (Subtarget->is64Bit() && !Subtarget->useSoftFloat()) {
setLibcallName(RTLIB::ADD_F128, "_Qp_add");
setLibcallName(RTLIB::SUB_F128, "_Qp_sub");
setLibcallName(RTLIB::MUL_F128, "_Qp_mul");
@@ -1778,7 +1780,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
setLibcallName(RTLIB::FPEXT_F64_F128, "_Qp_dtoq");
setLibcallName(RTLIB::FPROUND_F128_F32, "_Qp_qtos");
setLibcallName(RTLIB::FPROUND_F128_F64, "_Qp_qtod");
- } else {
+ } else if (!Subtarget->useSoftFloat()) {
setLibcallName(RTLIB::ADD_F128, "_Q_add");
setLibcallName(RTLIB::SUB_F128, "_Q_sub");
setLibcallName(RTLIB::MUL_F128, "_Q_mul");
@@ -1806,6 +1808,10 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
computeRegisterProperties(Subtarget->getRegisterInfo());
}
+bool SparcTargetLowering::useSoftFloat() const {
+ return Subtarget->useSoftFloat();
+}
+
const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {
switch ((SPISD::NodeType)Opcode) {
case SPISD::FIRST_NUMBER: break;
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h
index e451afa98fc..20dfd2cabd0 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.h
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.h
@@ -59,7 +59,9 @@ namespace llvm {
public:
SparcTargetLowering(const TargetMachine &TM, const SparcSubtarget &STI);
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
-
+
+ bool useSoftFloat() const override;
+
/// computeKnownBitsForTargetNode - Determine which of the bits specified
/// in Mask are known to be either zero or one and return them in the
/// KnownZero/KnownOne bitsets.
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
index 8049ae41314..f3b50d40323 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.cpp
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.cpp
@@ -34,6 +34,7 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(StringRef CPU,
IsVIS = false;
HasHardQuad = false;
UsePopc = false;
+ UseSoftFloat = false;
// Leon features
HasLeonCasa = false;
diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.h b/llvm/lib/Target/Sparc/SparcSubtarget.h
index c573965fb28..4ad963e31d8 100644
--- a/llvm/lib/Target/Sparc/SparcSubtarget.h
+++ b/llvm/lib/Target/Sparc/SparcSubtarget.h
@@ -39,6 +39,7 @@ class SparcSubtarget : public SparcGenSubtargetInfo {
bool Is64Bit;
bool HasHardQuad;
bool UsePopc;
+ bool UseSoftFloat;
// LEON features
bool HasUmacSmac;
@@ -77,6 +78,7 @@ public:
bool useDeprecatedV8Instructions() const { return V8DeprecatedInsts; }
bool hasHardQuad() const { return HasHardQuad; }
bool usePopc() const { return UsePopc; }
+ bool useSoftFloat() const { return UseSoftFloat; }
// Leon options
bool hasUmacSmac() const { return HasUmacSmac; }
diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
index fa6cc73c529..6e75c634d0e 100644
--- a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
+++ b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
@@ -62,13 +62,47 @@ SparcTargetMachine::SparcTargetMachine(const Target &T, const Triple &TT,
CodeGenOpt::Level OL, bool is64bit)
: LLVMTargetMachine(T, computeDataLayout(TT, is64bit), TT, CPU, FS, Options,
RM, CM, OL),
- TLOF(make_unique<SparcELFTargetObjectFile>()),
- Subtarget(TT, CPU, FS, *this, is64bit) {
+ TLOF(make_unique<SparcELFTargetObjectFile>()) {
initAsmInfo();
+ this->is64Bit = is64bit;
}
SparcTargetMachine::~SparcTargetMachine() {}
+const SparcSubtarget *
+SparcTargetMachine::getSubtargetImpl(const Function &F) const {
+ Attribute CPUAttr = F.getFnAttribute("target-cpu");
+ Attribute FSAttr = F.getFnAttribute("target-features");
+
+ std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
+ ? CPUAttr.getValueAsString().str()
+ : TargetCPU;
+ std::string FS = !FSAttr.hasAttribute(Attribute::None)
+ ? FSAttr.getValueAsString().str()
+ : TargetFS;
+
+ // FIXME: This is related to the code below to reset the target options,
+ // we need to know whether or not the soft float flag is set on the
+ // function, so we can enable it as a subtarget feature.
+ bool softFloat =
+ F.hasFnAttribute("use-soft-float") &&
+ F.getFnAttribute("use-soft-float").getValueAsString() == "true";
+
+ if (softFloat)
+ FS += FS.empty() ? "+soft-float" : ",+soft-float";
+
+ auto &I = SubtargetMap[CPU + FS];
+ if (!I) {
+ // This needs to be done before we create a new subtarget since any
+ // creation will depend on the TM and the code generation flags on the
+ // function that reside in TargetOptions.
+ resetTargetOptions(F);
+ I = llvm::make_unique<SparcSubtarget>(TargetTriple, CPU, FS, *this,
+ this->is64Bit);
+ }
+ return I.get();
+}
+
namespace {
/// Sparc Code Generator Pass Configuration Options.
class SparcPassConfig : public TargetPassConfig {
diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.h b/llvm/lib/Target/Sparc/SparcTargetMachine.h
index 903c2d15629..4da9d2ccba9 100644
--- a/llvm/lib/Target/Sparc/SparcTargetMachine.h
+++ b/llvm/lib/Target/Sparc/SparcTargetMachine.h
@@ -22,7 +22,8 @@ namespace llvm {
class SparcTargetMachine : public LLVMTargetMachine {
std::unique_ptr<TargetLoweringObjectFile> TLOF;
- SparcSubtarget Subtarget;
+ bool is64Bit;
+ mutable StringMap<std::unique_ptr<SparcSubtarget>> SubtargetMap;
public:
SparcTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
StringRef FS, const TargetOptions &Options,
@@ -30,9 +31,7 @@ public:
bool is64bit);
~SparcTargetMachine() override;
- const SparcSubtarget *getSubtargetImpl(const Function &) const override {
- return &Subtarget;
- }
+ const SparcSubtarget *getSubtargetImpl(const Function &) const override;
// Pass Pipeline Configuration
TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
OpenPOWER on IntegriCloud