diff options
Diffstat (limited to 'clang/lib/Basic')
| -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();  } | 

