]> granicus.if.org Git - clang/commitdiff
[PowerPC] Support powerpc64le as a syntax-checking target.
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Fri, 26 Jul 2013 01:36:11 +0000 (01:36 +0000)
committerBill Schmidt <wschmidt@linux.vnet.ibm.com>
Fri, 26 Jul 2013 01:36:11 +0000 (01:36 +0000)
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
lib/CodeGen/CGBuiltin.cpp
lib/CodeGen/TargetInfo.cpp
lib/Driver/Driver.cpp
lib/Driver/ToolChain.cpp
lib/Driver/ToolChains.cpp
lib/Driver/Tools.cpp
test/Driver/ppc-features.cpp
test/Preprocessor/init.c

index 20e504c0be5d65486b2359f54373b307a70946a1..596eb8cb1685abe4dc0ac48748b0e4e52020c2cf 100644 (file)
@@ -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<bool> &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<PPC64TargetInfo>(Triple);
+    default:
+      return new PPC64TargetInfo(Triple);
+    }
+
   case llvm::Triple::nvptx:
     return new NVPTX32TargetInfo(Triple);
   case llvm::Triple::nvptx64:
index 71664b8d3c0225d0135787f018688b7023ca1568..5b41237585c48f8e4a3278937d3ccfe772c1eeeb 100644 (file)
@@ -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;
index 5934ff3719398b06c72c0ac5b918a05c9db12958..3e7f7fedba68e9750f3d82e3b22e9a3264637995 100644 (file)
@@ -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:
index 91b6bc148f5efcef22c01bce64d2e69b868e4151..028ba623c4f9825024c5e874ef9489c7ba6e68b6 100644 (file)
@@ -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;
   }
index 8676f7f8df4c3668cc945a065ec871b8683c8057..4fe3560976704ca94bda4b85bbf160e8d9e50c6b 100644 (file)
@@ -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();
   }
index 90851b49ad0049bbc59b7b7b5a1f8419870cf6dc..090181b4826e4a539d53c729b6b04dd507ee987f 100644 (file)
@@ -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();
   }
 }
index 82bd872df847ba77872ddee597c7f26ad31f5d69..eb3c4f8569eeaa96705787dfc54af333d30493e5 100644 (file)
@@ -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
index 3ccac992f677370e4a013f0cea18e2c53e8e175a..b030998ad6e5d1b657072641790566d351e180b4 100644 (file)
@@ -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.
index 7beb3443702625e37d026528bda04dc7d4713e1d..fa5589c9359213b495493cd236a68c388ad55d52 100644 (file)
 // 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