From ea7fb0ce25acc04664a2e7c2b24af03cef2c0d1f Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Fri, 26 Jul 2013 01:36:11 +0000 Subject: [PATCH] [PowerPC] Support powerpc64le as a syntax-checking target. This patch provides basic support for powerpc64le as an LLVM target. However, use of this target will not actually generate little-endian code. Instead, use of the target will cause the correct little-endian built-in defines to be generated, so that code that tests for __LITTLE_ENDIAN__, for example, will be correctly parsed for syntax-only testing. Code generation will otherwise be the same as powerpc64 (big-endian), for now. The patch leaves open the possibility of creating a little-endian PowerPC64 back end, but there is no immediate intent to create such a thing. The new test case variant ensures that correct built-in defines for little-endian code are generated. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@187180 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Basic/Targets.cpp | 29 +++++++-- lib/CodeGen/CGBuiltin.cpp | 1 + lib/CodeGen/TargetInfo.cpp | 3 + lib/Driver/Driver.cpp | 8 +++ lib/Driver/ToolChain.cpp | 2 + lib/Driver/ToolChains.cpp | 16 ++++- lib/Driver/Tools.cpp | 20 ++++++- test/Driver/ppc-features.cpp | 2 +- test/Preprocessor/init.c | 113 +++++++++++++++++++++++++++++++++++ 9 files changed, 185 insertions(+), 9 deletions(-) diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 20e504c0be..596eb8cb16 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -268,6 +268,7 @@ public: case llvm::Triple::mipsel: case llvm::Triple::ppc: case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: this->MCountName = "_mcount"; break; case llvm::Triple::arm: @@ -631,6 +632,7 @@ class PPCTargetInfo : public TargetInfo { std::string CPU; public: PPCTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + BigEndian = (Triple.getArch() != llvm::Triple::ppc64le); LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble; } @@ -702,6 +704,8 @@ public: .Case("ppc", true) .Case("powerpc64", true) .Case("ppc64", true) + .Case("powerpc64le", true) + .Case("ppc64le", true) .Default(false); if (CPUKnown) @@ -867,10 +871,15 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, } // Target properties. - if (getTriple().getOS() != llvm::Triple::NetBSD && - getTriple().getOS() != llvm::Triple::OpenBSD) - Builder.defineMacro("_BIG_ENDIAN"); - Builder.defineMacro("__BIG_ENDIAN__"); + if (getTriple().getArch() == llvm::Triple::ppc64le) { + Builder.defineMacro("_LITTLE_ENDIAN"); + Builder.defineMacro("__LITTLE_ENDIAN__"); + } else { + if (getTriple().getOS() != llvm::Triple::NetBSD && + getTriple().getOS() != llvm::Triple::OpenBSD) + Builder.defineMacro("_BIG_ENDIAN"); + Builder.defineMacro("__BIG_ENDIAN__"); + } // Subtarget options. Builder.defineMacro("__NATURAL_ALIGNMENT__"); @@ -1006,6 +1015,7 @@ void PPCTargetInfo::getDefaultFeatures(llvm::StringMap &Features) const { .Case("pwr6", true) .Case("pwr7", true) .Case("ppc64", true) + .Case("ppc64le", true) .Default(false); Features["qpx"] = (CPU == "a2q"); @@ -1167,6 +1177,8 @@ public: }; } // end anonymous namespace. +// Note: ABI differences may eventually require us to have a separate +// TargetInfo for little endian. namespace { class PPC64TargetInfo : public PPCTargetInfo { public: @@ -2967,6 +2979,7 @@ public: case llvm::Triple::mipsel: case llvm::Triple::ppc: case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: // this->MCountName = "_mcount"; break; case llvm::Triple::arm: @@ -5236,6 +5249,14 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { return new PPC64TargetInfo(Triple); } + case llvm::Triple::ppc64le: + switch (os) { + case llvm::Triple::Linux: + return new LinuxTargetInfo(Triple); + default: + return new PPC64TargetInfo(Triple); + } + case llvm::Triple::nvptx: return new NVPTX32TargetInfo(Triple); case llvm::Triple::nvptx64: diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 71664b8d3c..5b41237585 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -1590,6 +1590,7 @@ Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, return EmitX86BuiltinExpr(BuiltinID, E); case llvm::Triple::ppc: case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: return EmitPPCBuiltinExpr(BuiltinID, E); default: return 0; diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 5934ff3719..3e7f7fedba 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -5416,6 +5416,9 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { return *(TheTargetCodeGenInfo = new PPC64_SVR4_TargetCodeGenInfo(Types)); else return *(TheTargetCodeGenInfo = new PPC64TargetCodeGenInfo(Types)); + case llvm::Triple::ppc64le: + assert(Triple.isOSBinFormatELF() && "PPC64 LE non-ELF not supported!"); + return *(TheTargetCodeGenInfo = new PPC64_SVR4_TargetCodeGenInfo(Types)); case llvm::Triple::nvptx: case llvm::Triple::nvptx64: diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 91b6bc148f..028ba623c4 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -736,6 +736,10 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { case llvm::Triple::ppc64: llvm::outs() << "ppc64;@m64" << "\n"; break; + + case llvm::Triple::ppc64le: + llvm::outs() << "ppc64le;@m64" << "\n"; + break; } return false; } @@ -758,6 +762,10 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { case llvm::Triple::ppc64: llvm::outs() << "ppc64" << "\n"; break; + + case llvm::Triple::ppc64le: + llvm::outs() << "ppc64le" << "\n"; + break; } return false; } diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index 8676f7f8df..4fe3560976 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -52,6 +52,8 @@ std::string ToolChain::getDefaultUniversalArchName() const { return "ppc"; case llvm::Triple::ppc64: return "ppc64"; + case llvm::Triple::ppc64le: + return "ppc64le"; default: return Triple.getArchName(); } diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 90851b49ad..090181b482 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -752,7 +752,7 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, else if (Name == "ppc970") DAL->AddJoinedArg(0, MCpu, "970"); - else if (Name == "ppc64") + else if (Name == "ppc64" || Name == "ppc64le") DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64)); else if (Name == "i386") @@ -1104,6 +1104,11 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector( "powerpc64-unknown-linux-gnu", "powerpc64-suse-linux", "ppc64-redhat-linux" }; + static const char *const PPC64LELibDirs[] = { "/lib64", "/lib" }; + static const char *const PPC64LETriples[] = { "powerpc64le-linux-gnu", + "powerpc64le-unknown-linux-gnu", + "powerpc64le-suse-linux", + "ppc64le-redhat-linux" }; static const char *const SystemZLibDirs[] = { "/lib64", "/lib" }; static const char *const SystemZTriples[] = { @@ -1214,6 +1219,12 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector( BiarchTripleAliases.append(PPCTriples, PPCTriples + llvm::array_lengthof(PPCTriples)); break; + case llvm::Triple::ppc64le: + LibDirs.append(PPC64LELibDirs, + PPC64LELibDirs + llvm::array_lengthof(PPC64LELibDirs)); + TripleAliases.append(PPC64LETriples, + PPC64LETriples + llvm::array_lengthof(PPC64LETriples)); + break; case llvm::Triple::systemz: LibDirs.append(SystemZLibDirs, SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs)); @@ -2124,6 +2135,9 @@ static std::string getMultiarchTriple(const llvm::Triple TargetTriple, case llvm::Triple::ppc64: if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64-linux-gnu")) return "powerpc64-linux-gnu"; + case llvm::Triple::ppc64le: + if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc64le-linux-gnu")) + return "powerpc64le-linux-gnu"; return TargetTriple.str(); } } diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 82bd872df8..eb3c4f8569 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -550,6 +550,7 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) { return true; return false; + case llvm::Triple::ppc64le: case llvm::Triple::systemz: return false; } @@ -1109,6 +1110,7 @@ static std::string getPPCTargetCPU(const ArgList &Args) { .Case("pwr7", "pwr7") .Case("powerpc", "ppc") .Case("powerpc64", "ppc64") + .Case("powerpc64le", "ppc64le") .Default(""); } @@ -1126,6 +1128,8 @@ void Clang::AddPPCTargetArgs(const ArgList &Args, if (TargetCPUName.empty() && !Triple.isOSDarwin()) { if (Triple.getArch() == llvm::Triple::ppc64) TargetCPUName = "ppc64"; + else if (Triple.getArch() == llvm::Triple::ppc64le) + TargetCPUName = "ppc64le"; else TargetCPUName = "ppc"; } @@ -2470,6 +2474,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, case llvm::Triple::ppc: case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: AddPPCTargetArgs(Args, CmdArgs); break; @@ -2913,9 +2918,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Report an error for -faltivec on anything other than PowerPC. if (const Arg *A = Args.getLastArg(options::OPT_faltivec)) if (!(getToolChain().getArch() == llvm::Triple::ppc || - getToolChain().getArch() == llvm::Triple::ppc64)) + getToolChain().getArch() == llvm::Triple::ppc64 || + getToolChain().getArch() == llvm::Triple::ppc64le)) D.Diag(diag::err_drv_argument_only_allowed_with) - << A->getAsString(Args) << "ppc/ppc64"; + << A->getAsString(Args) << "ppc/ppc64/ppc64le"; if (getToolChain().SupportsProfiling()) Args.AddLastArg(CmdArgs, options::OPT_pg); @@ -3949,6 +3955,8 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("ppc"); else if (Arch == llvm::Triple::ppc64) CmdArgs.push_back("ppc64"); + else if (Arch == llvm::Triple::ppc64le) + CmdArgs.push_back("ppc64le"); else CmdArgs.push_back(Args.MakeArgString(getToolChain().getArchName())); } @@ -3960,7 +3968,8 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, // here. if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc) CmdArgs.push_back("-m32"); - else if (Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::ppc64) + else if (Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::ppc64 || + Arch == llvm::Triple::ppc64le) CmdArgs.push_back("-m64"); if (Output.isFilename()) { @@ -5912,6 +5921,10 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-a64"); CmdArgs.push_back("-mppc64"); CmdArgs.push_back("-many"); + } else if (getToolChain().getArch() == llvm::Triple::ppc64le) { + CmdArgs.push_back("-a64"); + CmdArgs.push_back("-mppc64le"); + CmdArgs.push_back("-many"); } else if (getToolChain().getArch() == llvm::Triple::arm) { StringRef MArch = getToolChain().getArchName(); if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a") @@ -6057,6 +6070,7 @@ static StringRef getLinuxDynamicLinker(const ArgList &Args, } else if (ToolChain.getArch() == llvm::Triple::ppc) return "/lib/ld.so.1"; else if (ToolChain.getArch() == llvm::Triple::ppc64 || + ToolChain.getArch() == llvm::Triple::ppc64le || ToolChain.getArch() == llvm::Triple::systemz) return "/lib64/ld64.so.1"; else diff --git a/test/Driver/ppc-features.cpp b/test/Driver/ppc-features.cpp index 3ccac992f6..b030998ad6 100644 --- a/test/Driver/ppc-features.cpp +++ b/test/Driver/ppc-features.cpp @@ -12,7 +12,7 @@ // RUN: not %clang -target mips64-linux-gnu -faltivec -fsyntax-only %s 2>&1 | FileCheck %s // RUN: not %clang -target sparc-unknown-solaris -faltivec -fsyntax-only %s 2>&1 | FileCheck %s -// CHECK: invalid argument '-faltivec' only allowed with 'ppc/ppc64' +// CHECK: invalid argument '-faltivec' only allowed with 'ppc/ppc64/ppc64le' // Check that -fno-altivec and -mno-altivec correctly disable the altivec // target feature on powerpc. diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c index 7beb344370..fa5589c935 100644 --- a/test/Preprocessor/init.c +++ b/test/Preprocessor/init.c @@ -1728,6 +1728,119 @@ // PPC64:#define __ppc64__ 1 // PPC64:#define __ppc__ 1 // +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64le-none-none -target-cpu pwr7 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC64LE %s +// +// PPC64LE:#define _ARCH_PPC 1 +// PPC64LE:#define _ARCH_PPC64 1 +// PPC64LE:#define _ARCH_PPCGR 1 +// PPC64LE:#define _ARCH_PPCSQ 1 +// PPC64LE:#define _ARCH_PWR4 1 +// PPC64LE:#define _ARCH_PWR5 1 +// PPC64LE:#define _ARCH_PWR5X 1 +// PPC64LE:#define _ARCH_PWR6 1 +// PPC64LE:#define _ARCH_PWR6X 1 +// PPC64LE:#define _ARCH_PWR7 1 +// PPC64LE:#define _LITTLE_ENDIAN 1 +// PPC64LE:#define _LP64 1 +// PPC64LE:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +// PPC64LE:#define __CHAR16_TYPE__ unsigned short +// PPC64LE:#define __CHAR32_TYPE__ unsigned int +// PPC64LE:#define __CHAR_BIT__ 8 +// PPC64LE:#define __CHAR_UNSIGNED__ 1 +// PPC64LE:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 +// PPC64LE:#define __DBL_DIG__ 15 +// PPC64LE:#define __DBL_EPSILON__ 2.2204460492503131e-16 +// PPC64LE:#define __DBL_HAS_DENORM__ 1 +// PPC64LE:#define __DBL_HAS_INFINITY__ 1 +// PPC64LE:#define __DBL_HAS_QUIET_NAN__ 1 +// PPC64LE:#define __DBL_MANT_DIG__ 53 +// PPC64LE:#define __DBL_MAX_10_EXP__ 308 +// PPC64LE:#define __DBL_MAX_EXP__ 1024 +// PPC64LE:#define __DBL_MAX__ 1.7976931348623157e+308 +// PPC64LE:#define __DBL_MIN_10_EXP__ (-307) +// PPC64LE:#define __DBL_MIN_EXP__ (-1021) +// PPC64LE:#define __DBL_MIN__ 2.2250738585072014e-308 +// PPC64LE:#define __DECIMAL_DIG__ 33 +// PPC64LE:#define __FLT_DENORM_MIN__ 1.40129846e-45F +// PPC64LE:#define __FLT_DIG__ 6 +// PPC64LE:#define __FLT_EPSILON__ 1.19209290e-7F +// PPC64LE:#define __FLT_EVAL_METHOD__ 0 +// PPC64LE:#define __FLT_HAS_DENORM__ 1 +// PPC64LE:#define __FLT_HAS_INFINITY__ 1 +// PPC64LE:#define __FLT_HAS_QUIET_NAN__ 1 +// PPC64LE:#define __FLT_MANT_DIG__ 24 +// PPC64LE:#define __FLT_MAX_10_EXP__ 38 +// PPC64LE:#define __FLT_MAX_EXP__ 128 +// PPC64LE:#define __FLT_MAX__ 3.40282347e+38F +// PPC64LE:#define __FLT_MIN_10_EXP__ (-37) +// PPC64LE:#define __FLT_MIN_EXP__ (-125) +// PPC64LE:#define __FLT_MIN__ 1.17549435e-38F +// PPC64LE:#define __FLT_RADIX__ 2 +// PPC64LE:#define __INT16_TYPE__ short +// PPC64LE:#define __INT32_TYPE__ int +// PPC64LE:#define __INT64_C_SUFFIX__ L +// PPC64LE:#define __INT64_TYPE__ long int +// PPC64LE:#define __INT8_TYPE__ char +// PPC64LE:#define __INTMAX_MAX__ 9223372036854775807L +// PPC64LE:#define __INTMAX_TYPE__ long int +// PPC64LE:#define __INTMAX_WIDTH__ 64 +// PPC64LE:#define __INTPTR_TYPE__ long int +// PPC64LE:#define __INTPTR_WIDTH__ 64 +// PPC64LE:#define __INT_MAX__ 2147483647 +// PPC64LE:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L +// PPC64LE:#define __LDBL_DIG__ 31 +// PPC64LE:#define __LDBL_EPSILON__ 4.94065645841246544176568792868221e-324L +// PPC64LE:#define __LDBL_HAS_DENORM__ 1 +// PPC64LE:#define __LDBL_HAS_INFINITY__ 1 +// PPC64LE:#define __LDBL_HAS_QUIET_NAN__ 1 +// PPC64LE:#define __LDBL_MANT_DIG__ 106 +// PPC64LE:#define __LDBL_MAX_10_EXP__ 308 +// PPC64LE:#define __LDBL_MAX_EXP__ 1024 +// PPC64LE:#define __LDBL_MAX__ 1.79769313486231580793728971405301e+308L +// PPC64LE:#define __LDBL_MIN_10_EXP__ (-291) +// PPC64LE:#define __LDBL_MIN_EXP__ (-968) +// PPC64LE:#define __LDBL_MIN__ 2.00416836000897277799610805135016e-292L +// PPC64LE:#define __LITTLE_ENDIAN__ 1 +// PPC64LE:#define __LONG_DOUBLE_128__ 1 +// PPC64LE:#define __LONG_LONG_MAX__ 9223372036854775807LL +// PPC64LE:#define __LONG_MAX__ 9223372036854775807L +// PPC64LE:#define __LP64__ 1 +// PPC64LE:#define __NATURAL_ALIGNMENT__ 1 +// PPC64LE:#define __POINTER_WIDTH__ 64 +// PPC64LE:#define __POWERPC__ 1 +// PPC64LE:#define __PPC64__ 1 +// PPC64LE:#define __PPC__ 1 +// PPC64LE:#define __PTRDIFF_TYPE__ long int +// PPC64LE:#define __PTRDIFF_WIDTH__ 64 +// PPC64LE:#define __REGISTER_PREFIX__ +// PPC64LE:#define __SCHAR_MAX__ 127 +// PPC64LE:#define __SHRT_MAX__ 32767 +// PPC64LE:#define __SIG_ATOMIC_WIDTH__ 32 +// PPC64LE:#define __SIZEOF_DOUBLE__ 8 +// PPC64LE:#define __SIZEOF_FLOAT__ 4 +// PPC64LE:#define __SIZEOF_INT__ 4 +// PPC64LE:#define __SIZEOF_LONG_DOUBLE__ 16 +// PPC64LE:#define __SIZEOF_LONG_LONG__ 8 +// PPC64LE:#define __SIZEOF_LONG__ 8 +// PPC64LE:#define __SIZEOF_POINTER__ 8 +// PPC64LE:#define __SIZEOF_PTRDIFF_T__ 8 +// PPC64LE:#define __SIZEOF_SHORT__ 2 +// PPC64LE:#define __SIZEOF_SIZE_T__ 8 +// PPC64LE:#define __SIZEOF_WCHAR_T__ 4 +// PPC64LE:#define __SIZEOF_WINT_T__ 4 +// PPC64LE:#define __SIZE_MAX__ 18446744073709551615UL +// PPC64LE:#define __SIZE_TYPE__ long unsigned int +// PPC64LE:#define __SIZE_WIDTH__ 64 +// PPC64LE:#define __UINTMAX_TYPE__ long unsigned int +// PPC64LE:#define __USER_LABEL_PREFIX__ _ +// PPC64LE:#define __WCHAR_MAX__ 2147483647 +// PPC64LE:#define __WCHAR_TYPE__ int +// PPC64LE:#define __WCHAR_WIDTH__ 32 +// PPC64LE:#define __WINT_TYPE__ int +// PPC64LE:#define __WINT_WIDTH__ 32 +// PPC64LE:#define __ppc64__ 1 +// PPC64LE:#define __ppc__ 1 +// // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu a2q -fno-signed-char < /dev/null | FileCheck -check-prefix PPCA2Q %s // // PPCA2Q:#define _ARCH_A2 1 -- 2.40.0