]> granicus.if.org Git - clang/commitdiff
Add builtin for pclmulqdq instruction.
authorCraig Topper <craig.topper@gmail.com>
Thu, 31 May 2012 05:18:48 +0000 (05:18 +0000)
committerCraig Topper <craig.topper@gmail.com>
Thu, 31 May 2012 05:18:48 +0000 (05:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157733 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/BuiltinsX86.def
lib/Basic/Targets.cpp
lib/Headers/wmmintrin.h
test/CodeGen/pclmul-builtins.c [new file with mode: 0644]

index 0637a4eb5d35b30660251b4d31d86a062c5bd049..9361da6f3455bf67f7ffe211e587312c3012b02c 100644 (file)
@@ -385,6 +385,9 @@ BUILTIN(__builtin_ia32_aesdeclast128, "V2LLiV2LLiV2LLi", "")
 BUILTIN(__builtin_ia32_aesimc128, "V2LLiV2LLi", "")
 BUILTIN(__builtin_ia32_aeskeygenassist128, "V2LLiV2LLiIc", "")
 
+// CLMUL
+BUILTIN(__builtin_ia32_pclmulqdq128, "V2LLiV2LLiV2LLiIc", "")
+
 // AVX
 BUILTIN(__builtin_ia32_addsubpd256, "V4dV4dV4d", "")
 BUILTIN(__builtin_ia32_addsubps256, "V8fV8fV8f", "")
index 9f692294b42c2dbc3c141af1915029614e99a798..b5bfddac52ec3b86623da59033abfa8cce19e734 100644 (file)
@@ -1238,6 +1238,7 @@ class X86TargetInfo : public TargetInfo {
   } MMX3DNowLevel;
 
   bool HasAES;
+  bool HasPCLMUL;
   bool HasLZCNT;
   bool HasBMI;
   bool HasBMI2;
@@ -1388,8 +1389,9 @@ class X86TargetInfo : public TargetInfo {
 public:
   X86TargetInfo(const std::string& triple)
     : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow),
-      HasAES(false), HasLZCNT(false), HasBMI(false), HasBMI2(false),
-      HasPOPCNT(false), HasSSE4a(false), HasFMA4(false), CPU(CK_Generic) {
+      HasAES(false), HasPCLMUL(false), HasLZCNT(false), HasBMI(false),
+      HasBMI2(false), HasPOPCNT(false), HasSSE4a(false), HasFMA4(false),
+      CPU(CK_Generic) {
     BigEndian = false;
     LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
   }
@@ -1571,6 +1573,7 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
   Features["sse42"] = false;
   Features["sse4a"] = false;
   Features["aes"] = false;
+  Features["pclmul"] = false;
   Features["avx"] = false;
   Features["avx2"] = false;
   Features["lzcnt"] = false;
@@ -1631,18 +1634,19 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
   case CK_Corei7:
     setFeatureEnabled(Features, "mmx", true);
     setFeatureEnabled(Features, "sse4", true);
-    setFeatureEnabled(Features, "aes", true);
     break;
   case CK_Corei7AVX:
   case CK_CoreAVXi:
     setFeatureEnabled(Features, "mmx", true);
     setFeatureEnabled(Features, "avx", true);
     setFeatureEnabled(Features, "aes", true);
+    setFeatureEnabled(Features, "pclmul", true);
     break;
   case CK_CoreAVX2:
     setFeatureEnabled(Features, "mmx", true);
     setFeatureEnabled(Features, "avx2", true);
     setFeatureEnabled(Features, "aes", true);
+    setFeatureEnabled(Features, "pclmul", true);
     setFeatureEnabled(Features, "lzcnt", true);
     setFeatureEnabled(Features, "bmi", true);
     setFeatureEnabled(Features, "bmi2", true);
@@ -1695,6 +1699,7 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
     setFeatureEnabled(Features, "avx", true);
     setFeatureEnabled(Features, "sse4a", true);
     setFeatureEnabled(Features, "aes", true);
+    setFeatureEnabled(Features, "pclmul", true);
     break;
   case CK_C3_2:
     setFeatureEnabled(Features, "mmx", true);
@@ -1740,6 +1745,8 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
       Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = true;
     else if (Name == "aes")
       Features["aes"] = true;
+    else if (Name == "pclmul")
+      Features["pclmul"] = true;
     else if (Name == "avx")
       Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
         Features["ssse3"] = Features["sse41"] = Features["sse42"] =
@@ -1789,6 +1796,8 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
       Features["3dnowa"] = false;
     else if (Name == "aes")
       Features["aes"] = false;
+    else if (Name == "pclmul")
+      Features["pclmul"] = false;
     else if (Name == "avx")
       Features["avx"] = Features["avx2"] = Features["fma4"] = false;
     else if (Name == "avx2")
@@ -1826,6 +1835,11 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
       continue;
     }
 
+    if (Feature == "pclmul") {
+      HasPCLMUL = true;
+      continue;
+    }
+
     if (Feature == "lzcnt") {
       HasLZCNT = true;
       continue;
@@ -2038,6 +2052,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
   if (HasAES)
     Builder.defineMacro("__AES__");
 
+  if (HasPCLMUL)
+    Builder.defineMacro("__PCLMUL__");
+
   if (HasLZCNT)
     Builder.defineMacro("__LZCNT__");
 
@@ -2119,12 +2136,12 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
       .Case("avx2", SSELevel >= AVX2)
       .Case("bmi", HasBMI)
       .Case("bmi2", HasBMI2)
-      .Case("sse4a", HasSSE4a)
       .Case("fma4", HasFMA4)
       .Case("lzcnt", HasLZCNT)
       .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
       .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
       .Case("mmx", MMX3DNowLevel >= MMX)
+      .Case("pclmul", HasPCLMUL)
       .Case("popcnt", HasPOPCNT)
       .Case("sse", SSELevel >= SSE1)
       .Case("sse2", SSELevel >= SSE2)
@@ -2132,6 +2149,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
       .Case("ssse3", SSELevel >= SSSE3)
       .Case("sse41", SSELevel >= SSE41)
       .Case("sse42", SSELevel >= SSE42)
+      .Case("sse4a", HasSSE4a)
       .Case("x86", true)
       .Case("x86_32", PointerWidth == 32)
       .Case("x86_64", PointerWidth == 64)
index 8f588507ee56677c0babdb0b67c739e03d43c031..dca896fd65d8e4424abbcfd50fc6e41c62064f11 100644 (file)
 #ifndef _WMMINTRIN_H
 #define _WMMINTRIN_H
 
-#if !defined (__AES__)
-# error "AES instructions not enabled"
+#include <emmintrin.h>
+
+#if !defined (__AES__) && !defined (__PCLMUL__)
+# error "AES/PCLMUL instructions not enabled"
 #else
 
-#include <xmmintrin.h>
+#ifdef __AES__
 
 static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
 _mm_aesenc_si128(__m128i __V, __m128i __R)
@@ -64,4 +66,14 @@ _mm_aesimc_si128(__m128i __V)
   __builtin_ia32_aeskeygenassist128((C), (R))
 
 #endif /* __AES__ */
+
+#ifdef __PCLMUL__
+
+#define _mm_clmulepi64_si128(__X, __Y, __I) \
+  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(__X), \
+                                        (__v2di)(__m128i)(__Y), (char)(__I)))
+
+#endif /* __PCLMUL__ */
+
+#endif /* __AES__ || __PCLMUL__ */
 #endif /* _WMMINTRIN_H */
diff --git a/test/CodeGen/pclmul-builtins.c b/test/CodeGen/pclmul-builtins.c
new file mode 100644 (file)
index 0000000..cb0af28
--- /dev/null
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +pclmul -emit-llvm -o - | FileCheck %s
+
+// Don't include mm_malloc.h, it's system specific.
+#define __MM_MALLOC_H
+
+#include <wmmintrin.h>
+
+__m128i test_mm_clmulepi64_si128(__m128i a, __m128i b) {
+  // CHECK: @llvm.x86.pclmulqdq
+  return _mm_clmulepi64_si128(a, b, 0);
+}