Index: lib/Driver/ToolChain.cpp =================================================================== --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -303,12 +303,17 @@ // Thumb2 is the default for V7 on Darwin. // // FIXME: Thumb should just be another -target-feaure, not in the triple. + StringRef MCPU, MArch; + if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) + MCPU = A->getValue(); + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) + MArch = A->getValue(); std::string CPU = Triple.isOSBinFormatMachO() - ? tools::arm::getARMCPUForMArch(Args, Triple) - : tools::arm::getARMTargetCPU(Args, Triple); + ? tools::arm::getARMCPUForMArch(MArch, Triple) + : tools::arm::getARMTargetCPU(MCPU, MArch, Triple); StringRef Suffix = tools::arm::getLLVMArchSuffixForARM(CPU, - tools::arm::getARMArch(Args, Triple)); + tools::arm::getARMArch(MArch, Triple)); bool ThumbDefault = Suffix.startswith("v6m") || Suffix.startswith("v7m") || Suffix.startswith("v7em") || (Suffix.startswith("v7") && getTriple().isOSBinFormatMachO()); Index: lib/Driver/Tools.h =================================================================== --- lib/Driver/Tools.h +++ lib/Driver/Tools.h @@ -231,11 +231,11 @@ } // end namespace hexagon. namespace arm { - std::string getARMTargetCPU(const llvm::opt::ArgList &Args, + std::string getARMTargetCPU(StringRef CPU, StringRef Arch, const llvm::Triple &Triple); - const std::string getARMArch(const llvm::opt::ArgList &Args, + const std::string getARMArch(StringRef Arch, const llvm::Triple &Triple); - const char* getARMCPUForMArch(const llvm::opt::ArgList &Args, + const char* getARMCPUForMArch(StringRef Arch, const llvm::Triple &Triple); const char* getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch); Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -502,11 +502,36 @@ } } +// ARM tools start. + +// Get SubArch (vN). +static int getARMSubArchVersionNumber(const llvm::Triple &Triple) { + llvm::StringRef Arch = Triple.getArchName(); + return llvm::ARMTargetParser::parseArchVersion(Arch); +} + +// True if M-profile. +static bool isARMMProfile(const llvm::Triple &Triple) { + llvm::StringRef Arch = Triple.getArchName(); + unsigned Profile = llvm::ARMTargetParser::parseArchProfile(Arch); + return Profile == llvm::ARM::PK_M; +} + +// Get Arch/CPU from args. +static void getARMArchCPUFromArgs(const ArgList &Args, + llvm::StringRef &Arch, + llvm::StringRef &CPU) { + if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) + CPU = A->getValue(); + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) + Arch = A->getValue(); +} + // Handle -mhwdiv=. static void getARMHWDivFeatures(const Driver &D, const Arg *A, const ArgList &Args, + StringRef HWDiv, std::vector &Features) { - StringRef HWDiv = A->getValue(); if (HWDiv == "arm") { Features.push_back("+hwdiv-arm"); Features.push_back("-hwdiv"); @@ -526,22 +551,33 @@ // Handle -mfpu=. static void getARMFPUFeatures(const Driver &D, const Arg *A, const ArgList &Args, + StringRef FPU, std::vector &Features) { - StringRef FPU = A->getValue(); unsigned FPUID = llvm::ARMTargetParser::parseFPU(FPU); if (!llvm::ARMTargetParser::getFPUFeatures(FPUID, Features)) D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); } -static int getARMSubArchVersionNumber(const llvm::Triple &Triple) { - llvm::StringRef Arch = Triple.getArchName(); - return llvm::ARMTargetParser::parseArchVersion(Arch); +// Check -march=. +static void checkARMArchName(const Driver &D, const Arg *A, + const ArgList &Args, + llvm::StringRef ArchName, + const llvm::Triple &Triple) { + std::string MArch = arm::getARMArch(ArchName, Triple); + if (llvm::ARMTargetParser::parseArch(MArch) == llvm::ARM::AK_INVALID) + D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); } -static bool isARMMProfile(const llvm::Triple &Triple) { - llvm::StringRef Arch = Triple.getArchName(); - unsigned Profile = llvm::ARMTargetParser::parseArchProfile(Arch); - return Profile == llvm::ARM::PK_M; +// Check -mcpu=. +static void checkARMCPUName(const Driver &D, const Arg *A, + const ArgList &Args, + llvm::StringRef CPUName, + llvm::StringRef ArchName, + const llvm::Triple &Triple) { + std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple); + std::string Arch = arm::getARMArch(ArchName, Triple); + if (strcmp(arm::getLLVMArchSuffixForARM(CPU, Arch), "") == 0) + D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); } // Select the float ABI as determined by -msoft-float, -mhard-float, and @@ -665,27 +701,27 @@ // Honor -mfpu=. if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) - getARMFPUFeatures(D, A, Args, Features); + getARMFPUFeatures(D, A, Args, A->getValue(), Features); + // Honor -mhwdiv= if (const Arg *A = Args.getLastArg(options::OPT_mhwdiv_EQ)) - getARMHWDivFeatures(D, A, Args, Features); + getARMHWDivFeatures(D, A, Args, A->getValue(), Features); // Check if -march is valid by checking if it can be canonicalised and parsed. // getARMArch is used here instead of just checking the -march value in order // to handle -march=native correctly. + StringRef ArchName; if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { - std::string Arch = arm::getARMArch(Args, Triple); - if (llvm::ARMTargetParser::parseArch(Arch) == llvm::ARM::AK_INVALID) - D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); + ArchName = A->getValue(); + checkARMArchName(D, A, Args, ArchName, Triple); } // We do a similar thing with -mcpu, but here things are complicated because // the only function we have to check if a cpu is valid is // getLLVMArchSuffixForARM which also needs an architecture. + StringRef CPUName; if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { - std::string CPU = arm::getARMTargetCPU(Args, Triple); - std::string Arch = arm::getARMArch(Args, Triple); - if (strcmp(arm::getLLVMArchSuffixForARM(CPU, Arch), "") == 0) - D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); + CPUName = A->getValue(); + checkARMCPUName(D, A, Args, CPUName, ArchName, Triple); } // Setting -msoft-float effectively disables NEON because of the GCC @@ -836,6 +872,7 @@ CmdArgs.push_back("-arm-reserve-r9"); } } +// ARM tools end. /// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are /// targeting. @@ -1475,9 +1512,11 @@ case llvm::Triple::arm: case llvm::Triple::armeb: case llvm::Triple::thumb: - case llvm::Triple::thumbeb: - return arm::getARMTargetCPU(Args, T); - + case llvm::Triple::thumbeb: { + StringRef MArch, MCPU; + getARMArchCPUFromArgs(Args, MArch, MCPU); + return arm::getARMTargetCPU(MCPU, MArch, T); + } case llvm::Triple::mips: case llvm::Triple::mipsel: case llvm::Triple::mips64: @@ -5749,16 +5788,13 @@ } // Hexagon tools end. -const std::string arm::getARMArch(const ArgList &Args, +const std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) { std::string MArch; - if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { - // Otherwise, if we have -march= choose the base CPU for that arch. - MArch = A->getValue(); - } else { - // Otherwise, use the Arch from the triple. + if (!Arch.empty()) + MArch = Arch; + else MArch = Triple.getArchName(); - } MArch = StringRef(MArch).lower(); // Handle -march=native. @@ -5779,9 +5815,9 @@ return MArch; } /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting. -const char *arm::getARMCPUForMArch(const ArgList &Args, +const char *arm::getARMCPUForMArch(StringRef Arch, const llvm::Triple &Triple) { - std::string MArch = getARMArch(Args, Triple); + std::string MArch = getARMArch(Arch, Triple); // getARMCPUForArch defaults to the triple if MArch is empty, but empty MArch // here means an -march=native that we can't handle, so instead return no CPU. if (MArch.empty()) @@ -5797,12 +5833,13 @@ } /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting. -std::string arm::getARMTargetCPU(const ArgList &Args, +std::string arm::getARMTargetCPU(StringRef CPU, + StringRef Arch, const llvm::Triple &Triple) { // FIXME: Warn on inconsistent use of -mcpu and -march. // If we have -mcpu=, use that. - if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { - std::string MCPU = StringRef(A->getValue()).lower(); + if (!CPU.empty()) { + std::string MCPU = StringRef(CPU).lower(); // Handle -mcpu=native. if (MCPU == "native") return llvm::sys::getHostCPUName(); @@ -5810,7 +5847,7 @@ return MCPU; } - return getARMCPUForMArch(Args, Triple); + return getARMCPUForMArch(Arch, Triple); } /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular @@ -7309,8 +7346,10 @@ case llvm::Triple::armeb: case llvm::Triple::thumb: case llvm::Triple::thumbeb: { - std::string MArch = arm::getARMTargetCPU(Args, getToolChain().getTriple()); - CmdArgs.push_back(Args.MakeArgString("-mcpu=" + MArch)); + StringRef MArch, MCPU; + getARMArchCPUFromArgs(Args, MArch, MCPU); + std::string Arch = arm::getARMTargetCPU(MCPU, MArch, getToolChain().getTriple()); + CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch)); break; }