Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -617,6 +617,42 @@ } } +static int getARMSubArchVersionNumber(const llvm::Triple &Triple) { + switch (Triple.getSubArch()) { + case llvm::Triple::ARMSubArch_v8_1a: + case llvm::Triple::ARMSubArch_v8: + return 8; + case llvm::Triple::ARMSubArch_v7: + case llvm::Triple::ARMSubArch_v7em: + case llvm::Triple::ARMSubArch_v7m: + case llvm::Triple::ARMSubArch_v7s: + return 7; + case llvm::Triple::ARMSubArch_v6: + case llvm::Triple::ARMSubArch_v6m: + case llvm::Triple::ARMSubArch_v6k: + case llvm::Triple::ARMSubArch_v6t2: + return 6; + case llvm::Triple::ARMSubArch_v5: + case llvm::Triple::ARMSubArch_v5te: + return 5; + case llvm::Triple::ARMSubArch_v4t: + return 4; + default: + return 0; + } +} + +static bool isARMMProfile(const llvm::Triple &Triple) { + switch (Triple.getSubArch()) { + case llvm::Triple::ARMSubArch_v7em: + case llvm::Triple::ARMSubArch_v7m: + case llvm::Triple::ARMSubArch_v6m: + return true; + default: + return false; + } +} + // Select the float ABI as determined by -msoft-float, -mhard-float, and // -mfloat-abi=. StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args, @@ -647,12 +683,8 @@ case llvm::Triple::IOS: { // Darwin defaults to "softfp" for v6 and v7. // - // FIXME: Factor out an ARM class so we can cache the arch somewhere. - std::string ArchName = - arm::getLLVMArchSuffixForARM(arm::getARMTargetCPU(Args, Triple), - arm::getARMArch(Args, Triple)); - if (StringRef(ArchName).startswith("v6") || - StringRef(ArchName).startswith("v7")) + if (getARMSubArchVersionNumber(Triple) == 6 || + getARMSubArchVersionNumber(Triple) == 7) FloatABI = "softfp"; else FloatABI = "soft"; @@ -692,10 +724,7 @@ FloatABI = "softfp"; break; case llvm::Triple::Android: { - std::string ArchName = - arm::getLLVMArchSuffixForARM(arm::getARMTargetCPU(Args, Triple), - arm::getARMArch(Args, Triple)); - if (StringRef(ArchName).startswith("v7")) + if (getARMSubArchVersionNumber(Triple) == 7) FloatABI = "softfp"; else FloatABI = "soft"; @@ -748,13 +777,23 @@ if (const Arg *A = Args.getLastArg(options::OPT_mhwdiv_EQ)) getARMHWDivFeatures(D, A, Args, Features); - // -march is handled in getARMCPUForMarch by translating it into a CPU name, + // -march is handled in getARMCPUForMArch by translating it into a CPU name, // but it needs to return an empty string on invalid arguments. We therefore // check and give an error here if the -march is invalid. if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) - if (!Triple.getARMCPUForArch(A->getValue())) + if (strcmp(arm::getARMCPUForMArch(Args, Triple),"") == 0) D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); + // 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. + if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { + StringRef CPU = arm::getARMTargetCPU(Args, Triple); + StringRef Arch = arm::getARMArch(Args, Triple); + if (strcmp(arm::getLLVMArchSuffixForARM(CPU, Arch), "") == 0) + D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); + } + // Setting -msoft-float effectively disables NEON because of the GCC // implementation, although the same isn't true of VFP or VFP3. if (FloatABI == "soft") { @@ -783,7 +822,6 @@ // Get the effective triple, which takes into account the deployment target. std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args); llvm::Triple Triple(TripleStr); - std::string CPUName = arm::getARMTargetCPU(Args, Triple); // Select the ABI to use. // @@ -797,7 +835,7 @@ // the frontend matches that. if (Triple.getEnvironment() == llvm::Triple::EABI || Triple.getOS() == llvm::Triple::UnknownOS || - StringRef(CPUName).startswith("cortex-m")) { + isARMMProfile(Triple)) { ABIName = "aapcs"; } else { ABIName = "apcs-gnu"; @@ -3209,9 +3247,7 @@ } // Add the target cpu - std::string ETripleStr = getToolChain().ComputeEffectiveClangTriple(Args); - llvm::Triple ETriple(ETripleStr); - std::string CPU = getCPUName(Args, ETriple); + std::string CPU = getCPUName(Args, Triple); if (!CPU.empty()) { CmdArgs.push_back("-target-cpu"); CmdArgs.push_back(Args.MakeArgString(CPU)); @@ -3223,7 +3259,7 @@ } // Add the target features - getTargetFeatures(D, ETriple, Args, CmdArgs, false); + getTargetFeatures(D, Triple, Args, CmdArgs, false); // Add target specific flags. switch(getToolChain().getArch()) { @@ -5105,7 +5141,7 @@ CmdArgs.push_back(Clang::getBaseInputName(Args, Input)); // Add the target cpu - const llvm::Triple &Triple = getToolChain().getTriple(); + const llvm::Triple Triple(TripleStr); std::string CPU = getCPUName(Args, Triple); if (!CPU.empty()) { CmdArgs.push_back("-target-cpu"); @@ -5645,6 +5681,10 @@ // then chose the minimum cpu for that arch. MArch = std::string("arm") + arm::getLLVMArchSuffixForARM(CPU, arm::getARMArch(Args, Triple)); + // If there is no valid architecture suffix for this CPU then we don't + // know the correct minimum CPU, so don't return one. + if (MArch == "arm") + return ""; } } @@ -5690,7 +5730,8 @@ } return llvm::StringSwitch(CPU) - .Case("strongarm", "v4") + .Cases("arm8", "arm810", "v4") + .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "v4") .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t") .Cases("arm720t", "arm9", "arm9tdmi", "v4t") .Cases("arm920", "arm920t", "arm922t", "v4t") @@ -5720,15 +5761,10 @@ if (Args.hasArg(options::OPT_r)) return; - StringRef Suffix = getLLVMArchSuffixForARM(getARMCPUForMArch(Args, Triple), - getARMArch(Args, Triple)); - const char *LinkFlag = llvm::StringSwitch(Suffix) - .Cases("v4", "v4t", "v5", "v5e", nullptr) - .Cases("v6", "v6k", "v6t2", nullptr) - .Default("--be8"); - - if (LinkFlag) - CmdArgs.push_back(LinkFlag); + // ARMv7 (and later) and ARMv6-M do not support BE-32, so instruct the linker + // to generate BE-8 executables. + if (getARMSubArchVersionNumber(Triple) >= 7 || isARMMProfile(Triple)) + CmdArgs.push_back("--be8"); } mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) { @@ -7314,7 +7350,8 @@ break; case llvm::Triple::armeb: case llvm::Triple::thumbeb: - arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getTriple()); + arm::appendEBLinkFlags(Args, CmdArgs, + llvm::Triple(getToolChain().ComputeEffectiveClangTriple(Args))); CmdArgs.push_back("-m"); switch (getToolChain().getTriple().getEnvironment()) { case llvm::Triple::EABI: @@ -7890,7 +7927,8 @@ if (ToolChain.getArch() == llvm::Triple::armeb || ToolChain.getArch() == llvm::Triple::thumbeb) - arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getTriple()); + arm::appendEBLinkFlags(Args, CmdArgs, + llvm::Triple(getToolChain().ComputeEffectiveClangTriple(Args))); for (const auto &Opt : ToolChain.ExtraOpts) CmdArgs.push_back(Opt.c_str()); Index: test/Driver/arm-cortex-cpus.c =================================================================== --- test/Driver/arm-cortex-cpus.c +++ test/Driver/arm-cortex-cpus.c @@ -205,6 +205,10 @@ // RUN: %clang -target arm---eabihf -march=armbogusv7 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BOGUS-HF %s // CHECK-BOGUS-HF: error: the clang compiler does not support '-march=armbogusv7' +// ================== Check that a bogus CPU gives an error +// RUN: %clang -target arm -mcpu=bogus -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BOGUS-CPU %s +// CHECK-BOGUS-CPU: error: the clang compiler does not support '-mcpu=bogus' + // ================== Check default Architecture on each ARM11 CPU // RUN: %clang -target arm-linux-gnueabi -mcpu=arm1136j-s -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV6 %s // RUN: %clang -target arm-linux-gnueabi -mcpu=arm1136jf-s -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV6 %s