From 318eace49df9ff9686dddd904473884d329fc402 Mon Sep 17 00:00:00 2001 From: Igor Canadi Date: Fri, 4 Apr 2014 14:03:19 -0700 Subject: [PATCH] Dynamically choose SSE 4.2 Summary: Otherwise, if we compile on machine with SSE4.2 support and run it on machine without the support, we will fail. Test Plan: compiles, verified that isSse42() gets called. Reviewers: dhruba Reviewed By: dhruba CC: leveldb Differential Revision: https://reviews.facebook.net/D17505 --- util/crc32c.cc | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/util/crc32c.cc b/util/crc32c.cc index 9500c44c1..d27fb4be9 100644 --- a/util/crc32c.cc +++ b/util/crc32c.cc @@ -313,12 +313,14 @@ static inline void Slow_CRC32(uint64_t* l, uint8_t const **p) { table0_[c >> 24]; } -#ifdef __SSE4_2__ static inline void Fast_CRC32(uint64_t* l, uint8_t const **p) { +#ifdef __SSE4_2__ *l = _mm_crc32_u64(*l, LE_LOAD64(*p)); *p += 8; -} +#else + Slow_CRC32(l, p); #endif +} template uint32_t ExtendImpl(uint32_t crc, const char* buf, size_t size) { @@ -363,14 +365,22 @@ uint32_t ExtendImpl(uint32_t crc, const char* buf, size_t size) { return l ^ 0xffffffffu; } +// Detect if SS42 or not. +static bool isSSE42() { +#if defined(__GNUC__) && defined(__x86_64__) && !defined(IOS_CROSS_COMPILE) + uint32_t c_; + uint32_t d_; + __asm__("cpuid" : "=c"(c_), "=d"(d_) : "a"(1) : "ebx"); + return c_ & (1U << 20); // copied from CpuId.h in Folly. +#else + return false; +#endif +} + typedef uint32_t (*Function)(uint32_t, const char*, size_t); static inline Function Choose_Extend() { -#ifdef __SSE4_2__ - return ExtendImpl; -#else - return ExtendImpl; -#endif + return isSSE42() ? ExtendImpl : ExtendImpl; } Function ChosenExtend = Choose_Extend();