diff options
Diffstat (limited to 'clang/lib/Basic/Targets.cpp')
| -rw-r--r-- | clang/lib/Basic/Targets.cpp | 113 |
1 files changed, 79 insertions, 34 deletions
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 134b84b8dc7..7f7af988a54 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -7112,34 +7112,38 @@ public: return IsNan2008; } + bool processorSupportsGPR64() const { + return llvm::StringSwitch<bool>(CPU) + .Case("mips3", true) + .Case("mips4", true) + .Case("mips5", true) + .Case("mips64", true) + .Case("mips64r2", true) + .Case("mips64r3", true) + .Case("mips64r5", true) + .Case("mips64r6", true) + .Case("octeon", true) + .Default(false); + return false; + } + StringRef getABI() const override { return ABI; } bool setABI(const std::string &Name) override { - // FIXME: The Arch component on the triple actually has no bearing on - // whether the ABI is valid or not. It's features of the CPU that - // matters and the size of the GPR's in particular. - // However, we can't allow O32 on 64-bit processors just yet because - // the backend still checks the Arch component instead of the ABI in - // a few places. - if (getTriple().getArch() == llvm::Triple::mips || - getTriple().getArch() == llvm::Triple::mipsel) { - if (Name == "o32") { - setO32ABITypes(); - ABI = Name; - return true; - } + if (Name == "o32") { + setO32ABITypes(); + ABI = Name; + return true; } - if (getTriple().getArch() == llvm::Triple::mips64 || - getTriple().getArch() == llvm::Triple::mips64el) { - if (Name == "n32") { - setN32ABITypes(); - ABI = Name; - return true; - } - if (Name == "n64") { - setN64ABITypes(); - ABI = Name; - return true; - } + + if (Name == "n32") { + setN32ABITypes(); + ABI = Name; + return true; + } + if (Name == "n64") { + setN64ABITypes(); + ABI = Name; + return true; } return false; } @@ -7189,26 +7193,25 @@ public: } bool setCPU(const std::string &Name) override { - bool GPR64Required = ABI == "n32" || ABI == "n64"; CPU = Name; return llvm::StringSwitch<bool>(Name) - .Case("mips1", !GPR64Required) - .Case("mips2", !GPR64Required) + .Case("mips1", true) + .Case("mips2", true) .Case("mips3", true) .Case("mips4", true) .Case("mips5", true) - .Case("mips32", !GPR64Required) - .Case("mips32r2", !GPR64Required) - .Case("mips32r3", !GPR64Required) - .Case("mips32r5", !GPR64Required) - .Case("mips32r6", !GPR64Required) + .Case("mips32", true) + .Case("mips32r2", true) + .Case("mips32r3", true) + .Case("mips32r5", true) + .Case("mips32r6", true) .Case("mips64", true) .Case("mips64r2", true) .Case("mips64r3", true) .Case("mips64r5", true) .Case("mips64r6", true) .Case("octeon", true) - .Case("p5600", !GPR64Required) + .Case("p5600", true) .Default(false); } const std::string& getCPU() const { return CPU; } @@ -7537,6 +7540,45 @@ public: bool hasInt128Type() const override { return ABI == "n32" || ABI == "n64"; } + + bool validateTarget(DiagnosticsEngine &Diags) const override { + // FIXME: It's valid to use O32 on a 64-bit CPU but the backend can't handle + // this yet. It's better to fail here than on the backend assertion. + if (processorSupportsGPR64() && ABI == "o32") { + Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU; + return false; + } + + // 64-bit ABI's require 64-bit CPU's. + if (!processorSupportsGPR64() && (ABI == "n32" || ABI == "n64")) { + Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU; + return false; + } + + // FIXME: It's valid to use O32 on a mips64/mips64el triple but the backend + // can't handle this yet. It's better to fail here than on the + // backend assertion. + if ((getTriple().getArch() == llvm::Triple::mips64 || + getTriple().getArch() == llvm::Triple::mips64el) && + ABI == "o32") { + Diags.Report(diag::err_target_unsupported_abi_for_triple) + << ABI << getTriple().str(); + return false; + } + + // FIXME: It's valid to use N32/N64 on a mips/mipsel triple but the backend + // can't handle this yet. It's better to fail here than on the + // backend assertion. + if ((getTriple().getArch() == llvm::Triple::mips || + getTriple().getArch() == llvm::Triple::mipsel) && + (ABI == "n32" || ABI == "n64")) { + Diags.Report(diag::err_target_unsupported_abi_for_triple) + << ABI << getTriple().str(); + return false; + } + + return true; + } }; const Builtin::Info MipsTargetInfo::BuiltinInfo[] = { @@ -8473,5 +8515,8 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, Target->setSupportedOpenCLOpts(); + if (!Target->validateTarget(Diags)) + return nullptr; + return Target.release(); } |

