Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -7054,10 +7054,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"; } @@ -7094,17 +7106,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 @@ -2277,7 +2277,7 @@ if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies && TargetTriple.getOS() == llvm::Triple::Linux && - TargetTriple.getEnvironment() == llvm::Triple::GNU) { + TargetTriple.isGNUEnvironment()) { // Select mips-img-linux-gnu toolchain. for (auto Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) { if (Candidate->select(Flags, Result.SelectedMultilib)) { Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -1177,7 +1177,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 @@ -2253,6 +2253,14 @@ // Use the default target triple if unspecified. if (Opts.Triple.empty()) Opts.Triple = llvm::sys::getDefaultTargetTriple(); + + // Pass the ABI in the triple if the target prefers this, otherwise + // pass it in Opts.ABI. + llvm::Triple ABITriple = llvm::Triple(Opts.Triple).getABIVariant(Opts.ABI); + if (ABITriple.getArch() != llvm::Triple::UnknownArch) { + Opts.Triple = ABITriple.str(); + Opts.ABI = ""; + } } bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Index: tools/driver/cc1as_main.cpp =================================================================== --- tools/driver/cc1as_main.cpp +++ tools/driver/cc1as_main.cpp @@ -71,6 +71,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; @@ -136,6 +140,7 @@ public: AssemblerInvocation() { Triple = ""; + ABI = ""; NoInitialTextSection = 0; InputFile = "-"; OutputPath = "-"; @@ -187,6 +192,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); @@ -194,6 +200,12 @@ if (Opts.Triple.empty()) Opts.Triple = llvm::sys::getDefaultTargetTriple(); + llvm::Triple ABITriple = llvm::Triple(Opts.Triple).getABIVariant(Opts.ABI); + if (ABITriple.getArch() != llvm::Triple::UnknownArch) { + Opts.Triple = ABITriple.str(); + Opts.ABI = ""; + } + // Language Options Opts.IncludePaths = Args.getAllArgValues(OPT_I); Opts.NoInitialTextSection = Args.hasArg(OPT_n);