aboutsummaryrefslogtreecommitdiff
path: root/lib/Driver/Tools.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-09-10 23:00:09 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-09-10 23:00:09 +0000
commitcbd1933f83e2332b2d7add10459f80cc4e7eb7bf (patch)
tree14d8227a7be92ff3707f91a1ff1f512cc2a57118 /lib/Driver/Tools.cpp
parente6ad3f9fceef0ecc422ff26754ea069a5fd18c69 (diff)
Initial handling of -m{soft-float,hard-float,float-abi=} for ARM.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81471 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Driver/Tools.cpp')
-rw-r--r--lib/Driver/Tools.cpp64
1 files changed, 61 insertions, 3 deletions
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index ad1c50b4ae..05a73b9768 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -309,12 +309,70 @@ static std::string getLLVMTriple(const ToolChain &TC, const ArgList &Args) {
void Clang::AddARMTargetArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
+ const Driver &D = getToolChain().getHost().getDriver();
+
// Set the CPU based on -march= and -mcpu=.
CmdArgs.push_back(Args.MakeArgString("-mcpu=" + getARMTargetCPU(Args)));
- // FIXME: Set the "neon" feature.
- // FIXME: Set -soft-float.
- // FIXME: Set -float-abi=hard.
+ // Select the float ABI as determined by -msoft-float, -mhard-float, and
+ // -mfloat-abi=.
+ llvm::StringRef FloatABI;
+ if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
+ options::OPT_mhard_float,
+ options::OPT_mfloat_abi_EQ)) {
+ if (A->getOption().matches(options::OPT_msoft_float))
+ FloatABI = "soft";
+ else if (A->getOption().matches(options::OPT_mhard_float))
+ FloatABI = "hard";
+ else {
+ FloatABI = A->getValue(Args);
+ if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") {
+ D.Diag(clang::diag::err_drv_invalid_mfloat_abi)
+ << A->getAsString(Args);
+ FloatABI = "soft";
+ }
+ }
+ }
+
+ // If unspecified, choose the default based on the platform.
+ if (FloatABI.empty()) {
+ // FIXME: This is wrong for non-Darwin, we don't have a mechanism yet for
+ // distinguishing things like linux-eabi vs linux-elf.
+ switch (getToolChain().getTriple().getOS()) {
+ case llvm::Triple::Darwin: {
+ // Darwin defaults to "softfp" for v6 and v7.
+ //
+ // FIXME: Factor out an ARM class so we can cache the arch somewhere.
+ llvm::StringRef ArchName = getLLVMArchSuffixForARM(getARMTargetCPU(Args));
+ if (ArchName.startswith("v6") || ArchName.startswith("v7"))
+ FloatABI = "softfp";
+ else
+ FloatABI = "soft";
+ break;
+ }
+
+ default:
+ // Assume "soft", but warn the user we are guessing.
+ FloatABI = "soft";
+ D.Diag(clang::diag::warn_drv_assuming_mfloat_abi_is) << "soft";
+ break;
+ }
+ }
+
+ if (FloatABI == "soft") {
+ // Floating point operations and argument passing are soft.
+ //
+ // FIXME: This changes CPP defines, we need -target-soft-float.
+ CmdArgs.push_back("-soft-float");
+ CmdArgs.push_back("-float-abi=soft");
+ } else if (FloatABI == "softfp") {
+ // Floating point operations are hard, but argument passing is soft.
+ CmdArgs.push_back("-float-abi=soft");
+ } else {
+ // Floating point operations and argument passing are hard.
+ assert(FloatABI == "hard" && "Invalid float abi!");
+ CmdArgs.push_back("-float-abi=hard");
+ }
}
void Clang::AddX86TargetArgs(const ArgList &Args,