diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-09-10 23:00:09 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-09-10 23:00:09 +0000 |
commit | cbd1933f83e2332b2d7add10459f80cc4e7eb7bf (patch) | |
tree | 14d8227a7be92ff3707f91a1ff1f512cc2a57118 | |
parent | e6ad3f9fceef0ecc422ff26754ea069a5fd18c69 (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
-rw-r--r-- | include/clang/Basic/DiagnosticDriverKinds.td | 4 | ||||
-rw-r--r-- | include/clang/Driver/Options.def | 2 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 64 |
3 files changed, 67 insertions, 3 deletions
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index a33fa0843e..fc31d4902a 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -53,6 +53,8 @@ def err_drv_command_failed : Error< "%0 command failed with exit code %1 (use -v to see invocation)">; def err_drv_command_signalled : Error< "%0 command failed due to signal %1 (use -v to see invocation)">; +def err_drv_invalid_mfloat_abi : Error< + "invalid float ABI '%0'">; def warn_drv_input_file_unused : Warning< "%0: '%1' input unused when '%2' is present">; @@ -68,5 +70,7 @@ def warn_drv_not_using_clang_arch : Warning< "not using the clang compiler for the '%0' architecture">; def warn_drv_clang_unsupported : Warning< "the clang compiler does not support '%0'">; +def warn_drv_assuming_mfloat_abi_is : Warning< + "unknown platform, assuming -mfloat-abi=%0">; } diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def index bf28164f46..4961cc97f0 100644 --- a/include/clang/Driver/Options.def +++ b/include/clang/Driver/Options.def @@ -516,6 +516,8 @@ OPTION("-mconstant-cfstrings", mconstant_cfstrings, Flag, clang_ignored_m_Group, OPTION("-mcpu=", mcpu_EQ, Joined, m_Group, INVALID, "d", 0, 0, 0) OPTION("-mdynamic-no-pic", mdynamic_no_pic, Joined, m_Group, INVALID, "q", 0, 0, 0) OPTION("-mfix-and-continue", mfix_and_continue, Flag, clang_ignored_m_Group, INVALID, "", 0, 0, 0) +OPTION("-mfloat-abi=", mfloat_abi_EQ, Joined, m_Group, INVALID, "", 0, 0, 0) +OPTION("-mhard-float", mhard_float, Flag, m_Group, INVALID, "", 0, 0, 0) OPTION("-miphoneos-version-min=", miphoneos_version_min_EQ, Joined, m_Group, INVALID, "", 0, 0, 0) OPTION("-mkernel", mkernel, Flag, m_Group, INVALID, "", 0, 0, 0) OPTION("-mllvm", mllvm, Separate, INVALID, INVALID, "", 0, 0, 0) 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, |