Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -7145,10 +7145,22 @@ BigEndian = getTriple().getArch() == llvm::Triple::mips || getTriple().getArch() == llvm::Triple::mips64; - setABI((getTriple().getArch() == llvm::Triple::mips || - getTriple().getArch() == llvm::Triple::mipsel) - ? "o32" - : "n64"); + if (getTriple().getEnvironment() == llvm::Triple::ABI32 || + getTriple().getEnvironment() == llvm::Triple::GNUABI32 || + getTriple().getEnvironment() == llvm::Triple::AndroidABI32) + setABI("o32"); + else if (getTriple().getEnvironment() == llvm::Triple::ABIN32 || + getTriple().getEnvironment() == llvm::Triple::GNUABIN32) + setABI("n32"); + else if (getTriple().getEnvironment() == llvm::Triple::ABI64 || + getTriple().getEnvironment() == llvm::Triple::GNUABI64 || + getTriple().getEnvironment() == llvm::Triple::AndroidABI64) + setABI("n64"); + else + setABI((getTriple().getArch() == llvm::Triple::mips || + getTriple().getArch() == llvm::Triple::mipsel) + ? "o32" + : "n64"); CPU = ABI == "o32" ? "mips32r2" : "mips64r2"; } @@ -7185,17 +7197,20 @@ if (Name == "o32") { setO32ABITypes(); ABI = Name; + setDataLayout(); return true; } if (Name == "n32") { setN32ABITypes(); ABI = Name; + setDataLayout(); return true; } if (Name == "n64") { setN64ABITypes(); ABI = Name; + setDataLayout(); return true; } return false; Index: lib/Driver/ToolChains.cpp =================================================================== --- lib/Driver/ToolChains.cpp +++ lib/Driver/ToolChains.cpp @@ -2404,7 +2404,7 @@ if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies && TargetTriple.getOS() == llvm::Triple::Linux && - TargetTriple.getEnvironment() == llvm::Triple::GNU) + TargetTriple.isGNUEnvironment()) return findMipsImgMultilibs(Flags, NonExistent, Result); if (findMipsCsMultilibs(Flags, NonExistent, Result)) Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -1249,7 +1249,7 @@ // MIPS32r6 is the default for mips(el)?-img-linux-gnu and MIPS64r6 is the // default for mips64(el)?-img-linux-gnu. if (Triple.getVendor() == llvm::Triple::ImaginationTechnologies && - Triple.getEnvironment() == llvm::Triple::GNU) { + Triple.isGNUEnvironment()) { DefMips32CPU = "mips32r6"; DefMips64CPU = "mips64r6"; } Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -2306,6 +2306,16 @@ // Use the default target triple if unspecified. if (Opts.Triple.empty()) Opts.Triple = llvm::sys::getDefaultTargetTriple(); + + // Modify the Triple and ABI according to the Triple and ABI. + llvm::Triple ABITriple; + StringRef ABIName; + std::tie(ABITriple, ABIName) = + llvm::Triple(Opts.Triple).getABIVariant(Opts.ABI); + if (ABITriple.getArch() == llvm::Triple::UnknownArch) + Diags.Report(diag::err_target_unknown_abi) << Opts.ABI; + Opts.Triple = ABITriple.str(); + Opts.ABI = ABIName; } bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Index: tools/driver/cc1as_main.cpp =================================================================== --- tools/driver/cc1as_main.cpp +++ tools/driver/cc1as_main.cpp @@ -69,6 +69,10 @@ /// The name of the target triple to assemble for. std::string Triple; + /// The name of the ABI to assembler for or the empty string for the default + /// ABI. + std::string ABI; + /// If given, the name of the target CPU to determine which instructions /// are legal. std::string CPU; @@ -134,6 +138,7 @@ public: AssemblerInvocation() { Triple = ""; + ABI = ""; NoInitialTextSection = 0; InputFile = "-"; OutputPath = "-"; @@ -185,6 +190,7 @@ // Target Options Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple)); + Opts.ABI = Args.getLastArgValue(OPT_target_abi); Opts.CPU = Args.getLastArgValue(OPT_target_cpu); Opts.Features = Args.getAllArgValues(OPT_target_feature); @@ -192,6 +198,16 @@ if (Opts.Triple.empty()) Opts.Triple = llvm::sys::getDefaultTargetTriple(); + // Modify the Triple and ABI according to the Triple and ABI. + llvm::Triple ABITriple; + StringRef ABIName; + std::tie(ABITriple, ABIName) = + llvm::Triple(Opts.Triple).getABIVariant(Opts.ABI); + if (ABITriple.getArch() == llvm::Triple::UnknownArch) + Diags.Report(diag::err_target_unknown_abi) << Opts.ABI; + Opts.Triple = ABITriple.str(); + Opts.ABI = ABIName; + // Language Options Opts.IncludePaths = Args.getAllArgValues(OPT_I); Opts.NoInitialTextSection = Args.hasArg(OPT_n);