From: Akira Hatanaka Date: Fri, 23 Mar 2012 23:07:09 +0000 (+0000) Subject: Add support for MIPS' floating ABIs (hard, soft and single) to clang driver. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ad8d8a31b010ceac4cad2553f16fc1a77c4b2e5e;p=clang Add support for MIPS' floating ABIs (hard, soft and single) to clang driver. Patch by Simon Atanasyan. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153348 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index a4b5b4729c..d4e5d2d4d2 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -3440,11 +3440,19 @@ namespace { namespace { class MipsTargetInfoBase : public TargetInfo { std::string CPU; + bool SoftFloat; + bool SingleFloat; + protected: std::string ABI; + public: MipsTargetInfoBase(const std::string& triple, const std::string& ABIStr) - : TargetInfo(triple), ABI(ABIStr) {} + : TargetInfo(triple), + SoftFloat(false), SingleFloat(false), + ABI(ABIStr) + {} + virtual const char *getABI() const { return ABI.c_str(); } virtual bool setABI(const std::string &Name) = 0; virtual bool setCPU(const std::string &Name) { @@ -3455,8 +3463,19 @@ public: Features[ABI] = true; Features[CPU] = true; } + virtual void getArchDefines(const LangOptions &Opts, - MacroBuilder &Builder) const = 0; + MacroBuilder &Builder) const { + if (SoftFloat) + Builder.defineMacro("__mips_soft_float", Twine(1)); + else if (SingleFloat) + Builder.defineMacro("__mips_single_float", Twine(1)); + else if (!SoftFloat && !SingleFloat) + Builder.defineMacro("__mips_hard_float", Twine(1)); + else + llvm_unreachable("Invalid float ABI for Mips."); + } + virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const = 0; virtual void getTargetBuiltins(const Builtin::Info *&Records, @@ -3507,6 +3526,37 @@ public: // FIXME: Implement! return ""; } + + virtual bool setFeatureEnabled(llvm::StringMap &Features, + StringRef Name, + bool Enabled) const { + if (Name == "soft-float" || Name == "single-float") { + Features[Name] = Enabled; + return true; + } + return false; + } + + virtual void HandleTargetFeatures(std::vector &Features) { + SoftFloat = false; + SingleFloat = false; + + for (std::vector::iterator it = Features.begin(), + ie = Features.end(); it != ie; ++it) { + if (*it == "+single-float") { + SingleFloat = true; + break; + } + + if (*it == "+soft-float") { + SoftFloat = true; + // This option is front-end specific. + // Do not need to pass it to the backend. + Features.erase(it); + break; + } + } + } }; class Mips32TargetInfoBase : public MipsTargetInfoBase { @@ -3525,6 +3575,8 @@ public: } virtual void getArchDefines(const LangOptions &Opts, MacroBuilder &Builder) const { + MipsTargetInfoBase::getArchDefines(Opts, Builder); + Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0))); Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth())); Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth())); @@ -3642,6 +3694,8 @@ public: } virtual void getArchDefines(const LangOptions &Opts, MacroBuilder &Builder) const { + MipsTargetInfoBase::getArchDefines(Opts, Builder); + if (ABI == "n32") { Builder.defineMacro("__mips_n32"); Builder.defineMacro("_ABIN32", "2"); diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index bd65d6acc8..c0767c372f 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -787,31 +787,57 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args, CmdArgs.push_back("-target-abi"); CmdArgs.push_back(ABIName); - // Select the float ABI as determined by -msoft-float, -mhard-float, and + // Select the float ABI as determined by -msoft-float, -mhard-float, + // and -mfloat-abi=. StringRef FloatABI; if (Arg *A = Args.getLastArg(options::OPT_msoft_float, - options::OPT_mhard_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 != "single" && FloatABI != "hard") { + D.Diag(diag::err_drv_invalid_mfloat_abi) + << A->getAsString(Args); + FloatABI = "hard"; + } + } } // If unspecified, choose the default based on the platform. if (FloatABI.empty()) { - // Assume "soft", but warn the user we are guessing. - FloatABI = "soft"; - D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft"; + // Assume "hard", because it's a default value used by gcc. + // When we start to recognize specific target MIPS processors, + // we will be able to select the default more correctly. + FloatABI = "hard"; } if (FloatABI == "soft") { // Floating point operations and argument passing are soft. - // - // FIXME: This changes CPP defines, we need -target-soft-float. CmdArgs.push_back("-msoft-float"); - } else { + CmdArgs.push_back("-mfloat-abi"); + CmdArgs.push_back("soft"); + + // FIXME: Note, this is a hack. We need to pass the selected float + // mode to the MipsTargetInfoBase to define appropriate macros there. + // Now it is the only method. + CmdArgs.push_back("-target-feature"); + CmdArgs.push_back("+soft-float"); + } + else if (FloatABI == "single") { + // Restrict the use of hardware floating-point + // instructions to 32-bit operations. + CmdArgs.push_back("-target-feature"); + CmdArgs.push_back("+single-float"); + } + else { + // Floating point operations and argument passing are hard. assert(FloatABI == "hard" && "Invalid float abi!"); - CmdArgs.push_back("-mhard-float"); + CmdArgs.push_back("-mfloat-abi"); + CmdArgs.push_back("hard"); } }