diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index b51ac024de..aa5147f76f 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -1976,17 +1976,37 @@ namespace { class SparcV8TargetInfo : public TargetInfo { static const TargetInfo::GCCRegAlias GCCRegAliases[]; static const char * const GCCRegNames[]; + bool SoftFloat; public: SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { // FIXME: Support Sparc quad-precision long double? DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; } + virtual bool setFeatureEnabled(llvm::StringMap &Features, + const std::string &Name, + bool Enabled) const { + if (Name == "soft-float") + Features[Name] = Enabled; + else + return false; + + return true; + } + virtual void HandleTargetFeatures(std::vector &Features) { + SoftFloat = false; + for (unsigned i = 0, e = Features.size(); i != e; ++i) + if (Features[i] == "+soft-float") + SoftFloat = true; + } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { DefineStd(Builder, "sparc", Opts); Builder.defineMacro("__sparcv8"); Builder.defineMacro("__REGISTER_PREFIX__", ""); + + if (SoftFloat) + Builder.defineMacro("SOFT_FLOAT", "1"); } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index e28078deaa..4bf29751d1 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -619,6 +619,51 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args, } } +void Clang::AddSparcTargetArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + const Driver &D = getToolChain().getDriver(); + + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { + llvm::StringRef MArch = A->getValue(Args); + CmdArgs.push_back("-target-cpu"); + CmdArgs.push_back(MArch.str().c_str()); + } + + // Select the float ABI as determined by -msoft-float, -mhard-float, and + llvm::StringRef FloatABI; + if (Arg *A = Args.getLastArg(options::OPT_msoft_float, + options::OPT_mhard_float)) { + if (A->getOption().matches(options::OPT_msoft_float)) + FloatABI = "soft"; + else if (A->getOption().matches(options::OPT_mhard_float)) + FloatABI = "hard"; + } + + // If unspecified, choose the default based on the platform. + if (FloatABI.empty()) { + switch (getToolChain().getTriple().getOS()) { + 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("-msoft-float"); + CmdArgs.push_back("soft"); + CmdArgs.push_back("-target-feature"); + CmdArgs.push_back("+soft-float"); + } else { + assert(FloatABI == "hard" && "Invalid float abi!"); + CmdArgs.push_back("-mhard-float"); + } +} + void Clang::AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { if (!Args.hasFlag(options::OPT_mred_zone, @@ -1006,6 +1051,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, AddMIPSTargetArgs(Args, CmdArgs); break; + case llvm::Triple::sparc: + AddSparcTargetArgs(Args, CmdArgs); + break; + case llvm::Triple::x86: case llvm::Triple::x86_64: AddX86TargetArgs(Args, CmdArgs); diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h index edfb2df38e..782aa4867c 100644 --- a/lib/Driver/Tools.h +++ b/lib/Driver/Tools.h @@ -36,6 +36,7 @@ namespace tools { void AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; void AddMIPSTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; + void AddSparcTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; public: