summaryrefslogtreecommitdiffstats
path: root/clang/lib/Basic/Targets.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Basic/Targets.cpp')
-rw-r--r--clang/lib/Basic/Targets.cpp113
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();
}
OpenPOWER on IntegriCloud