diff options
| author | Chris Dewhurst <chris.dewhurst@lero.ie> | 2016-05-18 09:14:13 +0000 |
|---|---|---|
| committer | Chris Dewhurst <chris.dewhurst@lero.ie> | 2016-05-18 09:14:13 +0000 |
| commit | 68388a0a9988ee4ec762a1605f3884709391345b (patch) | |
| tree | bd2a02a3020efb8554b4bc50228ff1a0230a057c /llvm/lib/Target/Sparc | |
| parent | a7547183ecb79e71ac5290dd787260d905a1d334 (diff) | |
| download | bcm5719-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.td | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcISelLowering.cpp | 16 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcISelLowering.h | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcSubtarget.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcSubtarget.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcTargetMachine.cpp | 38 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcTargetMachine.h | 7 |
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; |

