diff options
author | dim <dim@FreeBSD.org> | 2014-03-26 07:31:57 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-03-26 07:31:57 +0000 |
commit | fb422e6d310915f9e2641190198698d922f7ef58 (patch) | |
tree | 8126abc77e6620e23932d186c7b2b75457af47a5 /contrib/llvm/tools/clang | |
parent | 5a582ae617991f602ee6f8a954a36fd749aa466c (diff) | |
download | FreeBSD-src-fb422e6d310915f9e2641190198698d922f7ef58.zip FreeBSD-src-fb422e6d310915f9e2641190198698d922f7ef58.tar.gz |
MFC r262613:
Merge the projects/clang-sparc64 branch back to head. This brings in
several updates from the llvm and clang trunks to make the sparc64
backend fully functional.
Apart from one patch to sys/sparc64/include/pcpu.h which is still under
discussion, this makes it possible to let clang fully build world and
kernel for sparc64.
Any assistance with testing this on actual sparc64 hardware is greatly
appreciated, as there will unavoidably be bugs left.
Many thanks go to Roman Divacky for his upstream work on getting the
sparc64 backend into shape.
MFC r262985:
Repair a few minor mismerges from r262261 in the clang-sparc64 project
branch. This is also to minimize differences with upstream.
Diffstat (limited to 'contrib/llvm/tools/clang')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Targets.cpp | 23 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp | 46 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp | 28 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Tools.cpp | 53 |
4 files changed, 143 insertions, 7 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp index bccd0d7..af9221b 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp @@ -4529,6 +4529,13 @@ public: UIntMaxType = UnsignedLong; } Int64Type = IntMaxType; + + // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit + // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned. + LongDoubleWidth = 128; + LongDoubleAlign = 128; + LongDoubleFormat = &llvm::APFloat::IEEEquad; + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; } virtual void getTargetDefines(const LangOptions &Opts, @@ -4545,6 +4552,22 @@ public: Builder.defineMacro("__sparcv9__"); } } + + virtual bool setCPU(const std::string &Name) { + bool CPUKnown = llvm::StringSwitch<bool>(Name) + .Case("v9", true) + .Case("ultrasparc", true) + .Case("ultrasparc3", true) + .Case("niagara", true) + .Case("niagara2", true) + .Case("niagara3", true) + .Case("niagara4", true) + .Default(false); + + // No need to store the CPU yet. There aren't any CPU-specific + // macros to define. + return CPUKnown; + } }; } // end anonymous namespace. diff --git a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp index 76acf87..45eaec6 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp @@ -5349,6 +5349,11 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit) const { if (!isAggregateTypeForABI(Ty)) return ABIArgInfo::getDirect(); + // If a C++ object has either a non-trivial copy constructor or a non-trivial + // destructor, it is passed with an explicit indirect pointer / sret pointer. + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) + return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); + // This is a small aggregate type that should be passed in registers. // Build a coercion type from the LLVM struct type. llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty)); @@ -5430,9 +5435,50 @@ class SparcV9TargetCodeGenInfo : public TargetCodeGenInfo { public: SparcV9TargetCodeGenInfo(CodeGenTypes &CGT) : TargetCodeGenInfo(new SparcV9ABIInfo(CGT)) {} + + int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { + return 14; + } + + bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, + llvm::Value *Address) const; }; } // end anonymous namespace +bool +SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, + llvm::Value *Address) const { + // This is calculated from the LLVM and GCC tables and verified + // against gcc output. AFAIK all ABIs use the same encoding. + + CodeGen::CGBuilderTy &Builder = CGF.Builder; + + llvm::IntegerType *i8 = CGF.Int8Ty; + llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4); + llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8); + + // 0-31: the 8-byte general-purpose registers + AssignToArrayRange(Builder, Address, Eight8, 0, 31); + + // 32-63: f0-31, the 4-byte floating-point registers + AssignToArrayRange(Builder, Address, Four8, 32, 63); + + // Y = 64 + // PSR = 65 + // WIM = 66 + // TBR = 67 + // PC = 68 + // NPC = 69 + // FSR = 70 + // CSR = 71 + AssignToArrayRange(Builder, Address, Eight8, 64, 71); + + // 72-87: d0-15, the 8-byte floating-point registers + AssignToArrayRange(Builder, Address, Eight8, 72, 87); + + return false; +} + //===----------------------------------------------------------------------===// // Xcore ABI Implementation diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp index 8a47e76..f5dc3dfb 100644 --- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp @@ -1164,6 +1164,13 @@ void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const { "powerpc64le-suse-linux", "ppc64le-redhat-linux" }; + static const char *const SPARCv8LibDirs[] = { "/lib32", "/lib" }; + static const char *const SPARCv8Triples[] = { "sparc-linux-gnu", + "sparcv8-linux-gnu" }; + static const char *const SPARCv9LibDirs[] = { "/lib64", "/lib" }; + static const char *const SPARCv9Triples[] = { "sparc64-linux-gnu", + "sparcv9-linux-gnu" }; + static const char *const SystemZLibDirs[] = { "/lib64", "/lib" }; static const char *const SystemZTriples[] = { "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", @@ -1283,6 +1290,26 @@ void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const { TripleAliases.append(PPC64LETriples, PPC64LETriples + llvm::array_lengthof(PPC64LETriples)); break; + case llvm::Triple::sparc: + LibDirs.append(SPARCv8LibDirs, + SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs)); + TripleAliases.append(SPARCv8Triples, + SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples)); + BiarchLibDirs.append(SPARCv9LibDirs, + SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs)); + BiarchTripleAliases.append( + SPARCv9Triples, SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples)); + break; + case llvm::Triple::sparcv9: + LibDirs.append(SPARCv9LibDirs, + SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs)); + TripleAliases.append(SPARCv9Triples, + SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples)); + BiarchLibDirs.append(SPARCv8LibDirs, + SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs)); + BiarchTripleAliases.append( + SPARCv8Triples, SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples)); + break; case llvm::Triple::systemz: LibDirs.append(SystemZLibDirs, SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs)); @@ -1379,6 +1406,7 @@ static bool findTargetBiarchSuffix(std::string &Suffix, StringRef Path, Suffix = "/n32"; else if (TargetArch == llvm::Triple::x86_64 || TargetArch == llvm::Triple::ppc64 || + TargetArch == llvm::Triple::sparcv9 || TargetArch == llvm::Triple::systemz || TargetArch == llvm::Triple::mips64 || TargetArch == llvm::Triple::mips64el) diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp index 3529fc7..b37b31c 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp @@ -1373,7 +1373,8 @@ static std::string getCPUName(const ArgList &Args, const llvm::Triple &T) { } case llvm::Triple::sparc: - if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) + case llvm::Triple::sparcv9: + if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) return A->getValue(); return ""; @@ -5785,6 +5786,24 @@ void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, default: CmdArgs.push_back("-matpcs"); } + } else if (getToolChain().getArch() == llvm::Triple::sparc || + getToolChain().getArch() == llvm::Triple::sparcv9) { + if (getToolChain().getArch() == llvm::Triple::sparc) + CmdArgs.push_back("-Av8plusa"); + else + CmdArgs.push_back("-Av9a"); + + Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, + options::OPT_fpic, options::OPT_fno_pic, + options::OPT_fPIE, options::OPT_fno_PIE, + options::OPT_fpie, options::OPT_fno_pie); + if (LastPICArg && + (LastPICArg->getOption().matches(options::OPT_fPIC) || + LastPICArg->getOption().matches(options::OPT_fpic) || + LastPICArg->getOption().matches(options::OPT_fPIE) || + LastPICArg->getOption().matches(options::OPT_fpie))) { + CmdArgs.push_back("-KPIC"); + } } Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, @@ -6194,6 +6213,7 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, const ArgList &Args, const char *LinkingOutput) const { ArgStringList CmdArgs; + bool NeedsKPIC = false; // Add --32/--64 to make sure we get the format we want. // This is incomplete @@ -6213,6 +6233,14 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-a64"); CmdArgs.push_back("-mppc64le"); CmdArgs.push_back("-many"); + } else if (getToolChain().getArch() == llvm::Triple::sparc) { + CmdArgs.push_back("-32"); + CmdArgs.push_back("-Av8plusa"); + NeedsKPIC = true; + } else if (getToolChain().getArch() == llvm::Triple::sparcv9) { + CmdArgs.push_back("-64"); + CmdArgs.push_back("-Av9a"); + NeedsKPIC = true; } else if (getToolChain().getArch() == llvm::Triple::arm) { StringRef MArch = getToolChain().getArchName(); if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a") @@ -6272,6 +6300,15 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString("-mmsa")); } + NeedsKPIC = true; + } else if (getToolChain().getArch() == llvm::Triple::systemz) { + // Always pass an -march option, since our default of z10 is later + // than the GNU assembler's default. + StringRef CPUName = getSystemZTargetCPU(Args); + CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName)); + } + + if (NeedsKPIC) { Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, options::OPT_fpic, options::OPT_fno_pic, options::OPT_fPIE, options::OPT_fno_PIE, @@ -6283,11 +6320,6 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, LastPICArg->getOption().matches(options::OPT_fpie))) { CmdArgs.push_back("-KPIC"); } - } else if (getToolChain().getArch() == llvm::Triple::systemz) { - // Always pass an -march option, since our default of z10 is later - // than the GNU assembler's default. - StringRef CPUName = getSystemZTargetCPU(Args); - CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName)); } Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, @@ -6357,7 +6389,8 @@ static StringRef getLinuxDynamicLinker(const ArgList &Args, const toolchains::Linux &ToolChain) { if (ToolChain.getTriple().getEnvironment() == llvm::Triple::Android) return "/system/bin/linker"; - else if (ToolChain.getArch() == llvm::Triple::x86) + else if (ToolChain.getArch() == llvm::Triple::x86 || + ToolChain.getArch() == llvm::Triple::sparc) return "/lib/ld-linux.so.2"; else if (ToolChain.getArch() == llvm::Triple::aarch64) return "/lib/ld-linux-aarch64.so.1"; @@ -6382,6 +6415,8 @@ static StringRef getLinuxDynamicLinker(const ArgList &Args, ToolChain.getArch() == llvm::Triple::ppc64le || ToolChain.getArch() == llvm::Triple::systemz) return "/lib64/ld64.so.1"; + else if (ToolChain.getArch() == llvm::Triple::sparcv9) + return "/lib64/ld-linux.so.2"; else return "/lib64/ld-linux-x86-64.so.2"; } @@ -6444,6 +6479,10 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("elf32ppclinux"); else if (ToolChain.getArch() == llvm::Triple::ppc64) CmdArgs.push_back("elf64ppc"); + else if (ToolChain.getArch() == llvm::Triple::sparc) + CmdArgs.push_back("elf32_sparc"); + else if (ToolChain.getArch() == llvm::Triple::sparcv9) + CmdArgs.push_back("elf64_sparc"); else if (ToolChain.getArch() == llvm::Triple::mips) CmdArgs.push_back("elf32btsmip"); else if (ToolChain.getArch() == llvm::Triple::mipsel) |