From: Leonardo Bianconi Date: Sun, 13 Sep 2015 16:47:49 +0000 (-0700) Subject: Port Folly to PPC64 X-Git-Tag: deprecate-dynamic-initializer~417 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=80c7ef06203a251bdc5ea88134847e386970f50d;p=folly.git Port Folly to PPC64 Summary: This patch adds PPC64 specific code in order to support this architecture and be able to be used by HHVM. Closes #299 Reviewed By: @simpkins Differential Revision: D2340723 Pulled By: @JoelMarcey --- diff --git a/folly/DiscriminatedPtr.h b/folly/DiscriminatedPtr.h index 115a1121..1054f595 100644 --- a/folly/DiscriminatedPtr.h +++ b/folly/DiscriminatedPtr.h @@ -34,8 +34,8 @@ #include #include -#if !FOLLY_X64 -# error "DiscriminatedPtr is x64-specific code." +#if !FOLLY_X64 && !FOLLY_PPC64 +# error "DiscriminatedPtr is x64 and ppc64 specific code." #endif namespace folly { diff --git a/folly/Hash.h b/folly/Hash.h index 07eb5571..194017fa 100644 --- a/folly/Hash.h +++ b/folly/Hash.h @@ -220,7 +220,8 @@ inline uint32_t fnv32(const char* s, inline uint32_t fnv32_buf(const void* buf, size_t n, uint32_t hash = FNV_32_HASH_START) { - const char* char_buf = reinterpret_cast(buf); + // forcing signed char, since other platforms can use unsigned + const signed char* char_buf = reinterpret_cast(buf); for (size_t i = 0; i < n; ++i) { hash += (hash << 1) + (hash << 4) + (hash << 7) + @@ -249,7 +250,8 @@ inline uint64_t fnv64(const char* s, inline uint64_t fnv64_buf(const void* buf, size_t n, uint64_t hash = FNV_64_HASH_START) { - const char* char_buf = reinterpret_cast(buf); + // forcing signed char, since other platforms can use unsigned + const signed char* char_buf = reinterpret_cast(buf); for (size_t i = 0; i < n; ++i) { hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + @@ -271,7 +273,8 @@ inline uint64_t fnv64(const std::string& str, #define get16bits(d) (*((const uint16_t*) (d))) inline uint32_t hsieh_hash32_buf(const void* buf, size_t len) { - const char* s = reinterpret_cast(buf); + // forcing signed char, since other platforms can use unsigned + const signed char* s = reinterpret_cast(buf); uint32_t hash = static_cast(len); uint32_t tmp; size_t rem; diff --git a/folly/PackedSyncPtr.h b/folly/PackedSyncPtr.h index 8205c6f8..97ff844c 100644 --- a/folly/PackedSyncPtr.h +++ b/folly/PackedSyncPtr.h @@ -19,8 +19,8 @@ #include -#if !FOLLY_X64 -# error "PackedSyncPtr is x64-specific code." +#if !FOLLY_X64 && !FOLLY_PPC64 +# error "PackedSyncPtr is x64 and ppc64 specific code." #endif /* diff --git a/folly/PicoSpinLock.h b/folly/PicoSpinLock.h index 2c1139cf..f2ca45c2 100644 --- a/folly/PicoSpinLock.h +++ b/folly/PicoSpinLock.h @@ -33,8 +33,8 @@ #include #include -#if !FOLLY_X64 && !FOLLY_A64 -# error "PicoSpinLock.h is currently x64 and aarch64 only." +#if !FOLLY_X64 && !FOLLY_A64 && !FOLLY_PPC64 +# error "PicoSpinLock.h is currently x64, aarch64 and ppc64 only." #endif namespace folly { @@ -128,8 +128,34 @@ struct PicoSpinLock { #undef FB_DOBTS #elif FOLLY_A64 ret = __atomic_fetch_or(&lock_, 1 << Bit, __ATOMIC_SEQ_CST); +#elif FOLLY_PPC64 +#define FB_DOBTS(size) \ + asm volatile("\teieio\n" \ + "\tl" #size "arx 14,0,%[lockPtr]\n" \ + "\tli 15,1\n" \ + "\tsldi 15,15,%[bit]\n" \ + "\tand. 16,15,14\n" \ + "\tbne 0f\n" \ + "\tor 14,14,15\n" \ + "\tst" #size "cx. 14,0,%[lockPtr]\n" \ + "\tbne 0f\n" \ + "\tori %[output],%[output],1\n" \ + "\tisync\n" \ + "0:\n" \ + : [output] "+r" (ret) \ + : [lockPtr] "r"(&lock_), \ + [bit] "i" (Bit) \ + : "cr0", "memory", "r14", "r15", "r16") + + switch (sizeof(IntType)) { + case 2: FB_DOBTS(h); break; + case 4: FB_DOBTS(w); break; + case 8: FB_DOBTS(d); break; + } + +#undef FB_DOBTS #else -#error "x86 aarch64 only" +#error "x86 aarch64 ppc64 only" #endif return ret; @@ -170,8 +196,30 @@ struct PicoSpinLock { #undef FB_DOBTR #elif FOLLY_A64 __atomic_fetch_and(&lock_, ~(1 << Bit), __ATOMIC_SEQ_CST); +#elif FOLLY_PPC64 +#define FB_DOBTR(size) \ + asm volatile("\teieio\n" \ + "0: l" #size "arx 14,0,%[lockPtr]\n" \ + "\tli 15,1\n" \ + "\tsldi 15,15,%[bit]\n" \ + "\txor 14,14,15\n" \ + "\tst" #size "cx. 14,0,%[lockPtr]\n" \ + "\tbne 0b\n" \ + "\tisync\n" \ + : \ + : [lockPtr] "r"(&lock_), \ + [bit] "i" (Bit) \ + : "cr0", "memory", "r14", "r15") + + switch (sizeof(IntType)) { + case 2: FB_DOBTR(h); break; + case 4: FB_DOBTR(w); break; + case 8: FB_DOBTR(d); break; + } + +#undef FB_DOBTR #else -# error "x64 aarch64 only" +# error "x64 aarch64 ppc64 only" #endif } }; diff --git a/folly/Portability.h b/folly/Portability.h index b990b302..17d07e20 100644 --- a/folly/Portability.h +++ b/folly/Portability.h @@ -132,6 +132,12 @@ # define FOLLY_A64 0 #endif +#if defined (__powerpc64__) +# define FOLLY_PPC64 1 +#else +# define FOLLY_PPC64 0 +#endif + // packing is very ugly in msvc #ifdef _MSC_VER # define FOLLY_PACK_ATTR /**/ @@ -355,6 +361,8 @@ inline void asm_volatile_pause() { asm volatile ("pause"); #elif FOLLY_A64 asm volatile ("wfe"); +#elif FOLLY_PPC64 + asm volatile("or 27,27,27"); #endif } inline void asm_pause() { @@ -364,6 +372,8 @@ inline void asm_pause() { asm ("pause"); #elif FOLLY_A64 asm ("wfe"); +#elif FOLLY_PPC64 + asm ("or 31,31,31"); #endif } diff --git a/folly/configure.ac b/folly/configure.ac index fad024da..b4d59e10 100644 --- a/folly/configure.ac +++ b/folly/configure.ac @@ -404,6 +404,8 @@ AC_SUBST([AM_LDFLAGS]) AM_CONDITIONAL([HAVE_STD_THREAD], [test "$ac_cv_header_features" = "yes"]) AM_CONDITIONAL([HAVE_X86_64], [test "$build_cpu" = "x86_64"]) +AM_CONDITIONAL([HAVE_PPC64], [test "$build_cpu" = "powerpc64le"]) +AM_CONDITIONAL([RUN_ARCH_SPECIFIC_TESTS], [test "$build_cpu" = "x86_64" || test "$build_cpu" = "powerpc64le"]) AM_CONDITIONAL([HAVE_LINUX], [test "$build_os" == "linux-gnu"]) AM_CONDITIONAL([HAVE_WEAK_SYMBOLS], [test "$folly_cv_prog_cc_weak_symbols" = "yes"]) diff --git a/folly/detail/MemoryIdler.cpp b/folly/detail/MemoryIdler.cpp index 07ec2fbb..f7af9ee8 100644 --- a/folly/detail/MemoryIdler.cpp +++ b/folly/detail/MemoryIdler.cpp @@ -92,7 +92,7 @@ void MemoryIdler::flushLocalMallocCaches() { // Stack madvise isn't Linux or glibc specific, but the system calls // and arithmetic (and bug compatibility) are not portable. The set of // platforms could be increased if it was useful. -#if FOLLY_X64 && defined(_GNU_SOURCE) && defined(__linux__) +#if (FOLLY_X64 || FOLLY_PPC64 ) && defined(_GNU_SOURCE) && defined(__linux__) static const size_t s_pageSize = sysconf(_SC_PAGESIZE); static FOLLY_TLS uintptr_t tls_stackLimit; diff --git a/folly/small_vector.h b/folly/small_vector.h index df237553..8f764136 100644 --- a/folly/small_vector.h +++ b/folly/small_vector.h @@ -48,7 +48,7 @@ #include #include -#if defined(__GNUC__) && FOLLY_X64 +#if defined(__GNUC__) && (FOLLY_X64 || FOLLY_PPC64) # include # define FB_PACK_ATTR FOLLY_PACK_ATTR # define FB_PACK_PUSH FOLLY_PACK_PUSH @@ -1058,7 +1058,7 @@ private: } } FB_PACK_ATTR; -#if FOLLY_X64 +#if (FOLLY_X64 || FOLLY_PPC64) typedef unsigned char InlineStorageType[sizeof(value_type) * MaxInline]; #else typedef typename std::aligned_storage< diff --git a/folly/test/Makefile.am b/folly/test/Makefile.am index f2af913b..81076c59 100644 --- a/folly/test/Makefile.am +++ b/folly/test/Makefile.am @@ -30,7 +30,7 @@ spin_lock_test_SOURCES = SpinLockTest.cpp spin_lock_test_LDADD = libgtestmain.la $(top_builddir)/libfolly.la TESTS += spin_lock_test -if HAVE_X86_64 +if RUN_ARCH_SPECIFIC_TESTS small_locks_test_SOURCES = SmallLocksTest.cpp small_locks_test_LDADD = libgtestmain.la $(top_builddir)/libfolly.la TESTS += small_locks_test @@ -48,10 +48,12 @@ discriminated_ptr_test_SOURCES = DiscriminatedPtrTest.cpp discriminated_ptr_test_LDADD = libgtestmain.la $(top_builddir)/libfolly.la TESTS += discriminated_ptr_test +if !HAVE_PPC64 cpuid_test_SOURCES = CpuIdTest.cpp cpuid_test_LDADD = libgtestmain.la $(top_builddir)/libfolly.la TESTS += cpuid_test endif +endif sorted_vector_types_test_SOURCES = sorted_vector_test.cpp sorted_vector_types_test_LDADD = libgtestmain.la $(top_builddir)/libfolly.la diff --git a/folly/test/small_vector_test.cpp b/folly/test/small_vector_test.cpp index f31bafa7..746fc27f 100644 --- a/folly/test/small_vector_test.cpp +++ b/folly/test/small_vector_test.cpp @@ -32,7 +32,7 @@ using folly::small_vector; using namespace folly::small_vector_policy; -#if FOLLY_X64 +#if FOLLY_X64 || FOLLY_PPC64 static_assert(sizeof(small_vector) == 16, "Object size is not what we expect for small_vector");