ARM: Use front-end specific target features "soft-float" and "soft-float-abi" to communicate FP mode to target; __SOFTFP__ is set correctly now.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91755 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 7cc9f73..66d1814 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -1187,7 +1187,11 @@
static const char * const GCCRegNames[];
std::string ABI, CPU;
- bool IsThumb;
+ unsigned IsThumb : 1;
+
+ // Initialized via features.
+ unsigned SoftFloat : 1;
+ unsigned SoftFloatABI : 1;
public:
ARMTargetInfo(const std::string &TripleStr)
@@ -1240,6 +1244,36 @@
return true;
}
+
+ virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
+ const std::string &Name,
+ bool Enabled) const {
+ if (Name != "soft-float" && Name != "soft-float-abi")
+ return false;
+
+ Features[Name] = Enabled;
+ return true;
+ }
+
+ virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
+ SoftFloat = SoftFloatABI = false;
+ for (unsigned i = 0, e = Features.size(); i != e; ++i) {
+ if (Features[i] == "+soft-float")
+ SoftFloat = true;
+ else if (Features[i] == "+soft-float-abi")
+ SoftFloatABI = true;
+ }
+
+ // Remove front-end specific options which the backend handles differently.
+ std::vector<std::string>::iterator it;
+ it = std::find(Features.begin(), Features.end(), "+soft-float");
+ if (it != Features.end())
+ Features.erase(it);
+ it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
+ if (it != Features.end())
+ Features.erase(it);
+ }
+
static const char *getCPUDefineSuffix(llvm::StringRef Name) {
return llvm::StringSwitch<const char*>(Name)
.Cases("arm8", "arm810", "4")
@@ -1294,9 +1328,7 @@
if (ABI == "aapcs" || ABI == "aapcs-linux")
Define(Defs, "__ARM_EABI__");
- // FIXME: This isn't correct, this should be set based on the various float
- // options.
- if (CPUArch[0] <= '5')
+ if (SoftFloat)
Define(Defs, "__SOFTFP__");
if (CPU == "xscale")
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index b1846b3..3dcdbbc 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -230,7 +230,7 @@
if (MArch == "armv5e" || MArch == "armv5te")
return "arm1026ejs";
if (MArch == "armv5tej")
- return "arm926ejs";
+ return "arm926ej-s";
if (MArch == "armv6" || MArch == "armv6k")
return "arm1136jf-s";
if (MArch == "armv6j")
@@ -432,6 +432,24 @@
CmdArgs.push_back("-mfloat-abi");
CmdArgs.push_back("hard");
}
+
+ // Set appropriate target features for floating point mode.
+ //
+ // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
+ // yet (it uses the -mfloat-abi and -msoft-float options above), and it is
+ // stripped out by the ARM target.
+
+ // Use software floating point operations?
+ if (FloatABI == "soft") {
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("+soft-float");
+ }
+
+ // Use software floating point argument passing?
+ if (FloatABI != "hard") {
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back("+soft-float-abi");
+ }
}
void Clang::AddX86TargetArgs(const ArgList &Args,