Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND CMAKE_GENERATOR_PLATFORM STREQUA
ELSEIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64")
MESSAGE(STATUS "Building for AArch64")
SET(EMBREE_ARM ON)
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64")
MESSAGE(STATUS "Building for PowerPC64")
SET(EMBREE_PPC64 ON)
ENDIF()

SET(EMBREE_TASKING_SYSTEM "TBB" CACHE STRING "Selects tasking system")
Expand Down Expand Up @@ -369,6 +372,8 @@ ENDIF()

IF (EMBREE_ARM)
SET_PROPERTY(CACHE EMBREE_MAX_ISA PROPERTY STRINGS NONE NEON NEON2X)
ELSEIF (EMBREE_PPC64)
SET_PROPERTY(CACHE EMBREE_MAX_ISA PROPERTY STRINGS NONE SSE2 SSE4.2 DEFAULT)
ELSE()
SET_PROPERTY(CACHE EMBREE_MAX_ISA PROPERTY STRINGS NONE SSE2 SSE4.2 AVX AVX2 AVX512 APX DEFAULT)
ENDIF()
Expand All @@ -388,6 +393,13 @@ IF (EMBREE_MAX_ISA STREQUAL "NONE")
TRY_COMPILE(COMPILER_SUPPORTS_AVX2 "${CMAKE_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/common/cmake/check_isa.cpp" COMPILE_DEFINITIONS ${FLAGS_AVX2})
TRY_COMPILE(COMPILER_SUPPORTS_AVX512 "${CMAKE_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/common/cmake/check_isa.cpp" COMPILE_DEFINITIONS ${FLAGS_AVX512})
TRY_COMPILE(COMPILER_SUPPORTS_APX "${CMAKE_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/common/cmake/check_isa.cpp" COMPILE_DEFINITIONS ${FLAGS_APX})
IF (EMBREE_PPC64)
# the probes pass trivially without any x86 flags
SET(COMPILER_SUPPORTS_AVX OFF)
SET(COMPILER_SUPPORTS_AVX2 OFF)
SET(COMPILER_SUPPORTS_AVX512 OFF)
SET(COMPILER_SUPPORTS_APX OFF)
ENDIF ()

OPTION(EMBREE_ISA_SSE2 "Enables SSE2 ISA." ON)
OPTION(EMBREE_ISA_SSE42 "Enables SSE4.2 ISA." ON)
Expand Down Expand Up @@ -502,6 +514,10 @@ IF(CMAKE_CXX_COMPILER_WRAPPER STREQUAL "CrayPrgEnv")
SET(EMBREE_ISA_SSE42 OFF)
ENDIF()

IF (EMBREE_PPC64 AND (EMBREE_ISA_AVX OR EMBREE_ISA_AVX2 OR EMBREE_ISA_AVX512 OR EMBREE_ISA_APX))
MESSAGE(FATAL_ERROR "PowerPC64 only supports the SSE2 and SSE4.2 ISAs (the x86 intrinsic wrappers do not cover AVX).")
ENDIF()

IF (APPLE AND EMBREE_STATIC_LIB)

# count number of set ISAs
Expand Down Expand Up @@ -563,6 +579,10 @@ IF (EMBREE_ARM)
ENDIF()
ENDIF()

IF (EMBREE_PPC64)
LIST(APPEND ISPC_TARGETS "vsx-i32x4")
ENDIF()

IF (EMBREE_ISA_NEON)
SET(EMBREE_ISA_SSE2 ON)
ENDIF()
Expand All @@ -576,7 +596,7 @@ ENDIF()

IF (EMBREE_ISA_SSE2)
ADD_DEFINITIONS(-DEMBREE_TARGET_SSE2)
IF (NOT EMBREE_ARM)
IF (NOT EMBREE_ARM AND NOT EMBREE_PPC64)
LIST(APPEND ISPC_TARGETS "sse2")
ENDIF()
IF(NOT FLAGS_LOWEST)
Expand All @@ -587,7 +607,7 @@ ENDIF()

IF (EMBREE_ISA_SSE42)
ADD_DEFINITIONS(-DEMBREE_TARGET_SSE42)
IF (NOT EMBREE_ARM)
IF (NOT EMBREE_ARM AND NOT EMBREE_PPC64)
LIST(APPEND ISPC_TARGETS "sse4")
ENDIF()
IF(NOT FLAGS_LOWEST)
Expand Down
8 changes: 8 additions & 0 deletions common/cmake/clang.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ IF (EMBREE_ARM)
SET(FLAGS_AVX "-D__AVX__ -D__SSE4_2__ -D__SSE4_1__ -D__BMI__ -D__BMI2__ -D__LZCNT__")
SET(FLAGS_AVX2 "-D__AVX2__ -D__AVX__ -D__SSE4_2__ -D__SSE4_1__ -D__BMI__ -D__BMI2__ -D__LZCNT__")
ENDIF ()
ELSEIF (EMBREE_PPC64)
# the x86 intrinsic wrappers need POWER8, honor a newer -mcpu from the user
STRING(REGEX MATCH "-mcpu=[^ ]+" FLAGS_PPC64_CPU "${CMAKE_CXX_FLAGS}")
IF (NOT FLAGS_PPC64_CPU)
SET(FLAGS_PPC64_CPU "-mcpu=power8")
ENDIF ()
SET(FLAGS_SSE2 "-D__SSE__ -D__SSE2__ ${FLAGS_PPC64_CPU}")
SET(FLAGS_SSE42 "-D__SSE4_2__ -D__SSE4_1__ ${FLAGS_PPC64_CPU}")
ELSE ()
# for `thread` keyword
_SET_IF_EMPTY(FLAGS_SSE2 "-msse -msse2 -mno-sse4.2")
Expand Down
13 changes: 13 additions & 0 deletions common/cmake/gnu.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ IF (EMBREE_ARM)
SET(FLAGS_SSE42 "-D__SSE4_2__ -D__SSE4_1__")
SET(FLAGS_AVX "-D__AVX__ -D__SSE4_2__ -D__SSE4_1__ -D__BMI__ -D__BMI2__ -D__LZCNT__")
SET(FLAGS_AVX2 "-D__AVX2__ -D__AVX__ -D__SSE4_2__ -D__SSE4_1__ -D__BMI__ -D__BMI2__ -D__LZCNT__")
ELSEIF (EMBREE_PPC64)
# GCC ships the x86 intrinsic wrappers for PowerPC since GCC 8, but
# immintrin.h (which intrinsics.h includes) only since GCC 12
IF (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0")
MESSAGE(FATAL_ERROR "GCC ${CMAKE_CXX_COMPILER_VERSION} lacks the PowerPC x86 intrinsic wrappers, GCC 12 or newer is required.")
ENDIF ()
# the x86 intrinsic wrappers need POWER8, honor a newer -mcpu from the user
STRING(REGEX MATCH "-mcpu=[^ ]+" FLAGS_PPC64_CPU "${CMAKE_CXX_FLAGS}")
IF (NOT FLAGS_PPC64_CPU)
SET(FLAGS_PPC64_CPU "-mcpu=power8")
ENDIF ()
SET(FLAGS_SSE2 "-D__SSE__ -D__SSE2__ ${FLAGS_PPC64_CPU}")
SET(FLAGS_SSE42 "-D__SSE4_2__ -D__SSE4_1__ ${FLAGS_PPC64_CPU}")
ELSE ()
_SET_IF_EMPTY(FLAGS_SSE2 "-msse2")
_SET_IF_EMPTY(FLAGS_SSE42 "-msse4.2")
Expand Down
2 changes: 2 additions & 0 deletions common/cmake/ispc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ MACRO (ISPC_COMPILE)
IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
IF (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64|aarch64")
SET(ISPC_ARCHITECTURE "aarch64")
ELSEIF (${CMAKE_SYSTEM_PROCESSOR} MATCHES "^(powerpc|ppc)64le")
SET(ISPC_ARCHITECTURE "ppc64le")
ELSE()
SET(ISPC_ARCHITECTURE "x86-64")
ENDIF()
Expand Down
30 changes: 30 additions & 0 deletions common/sys/intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,36 @@
#include "../simd/arm/emulation.h"
#else
#include <immintrin.h>
#if defined(__powerpc64__)
__forceinline unsigned int _mm_getcsr() { return 0; }
__forceinline void _mm_setcsr(unsigned int) {}
__forceinline int _mm_popcnt_u32(unsigned int v) { return __builtin_popcount(v); }
__forceinline long long _mm_popcnt_u64(unsigned long long v) { return __builtin_popcountll(v); }
__forceinline __m128i _mm_stream_load_si128(__m128i* p) { return _mm_load_si128(p); }
__forceinline __m128 _mm_dp_ps(__m128 a, __m128 b, const int imm) {
const __m128i hi = _mm_set_epi32((imm & 0x80) ? -1 : 0, (imm & 0x40) ? -1 : 0, (imm & 0x20) ? -1 : 0, (imm & 0x10) ? -1 : 0);
const __m128i lo = _mm_set_epi32((imm & 0x08) ? -1 : 0, (imm & 0x04) ? -1 : 0, (imm & 0x02) ? -1 : 0, (imm & 0x01) ? -1 : 0);
__m128 p = _mm_and_ps(_mm_mul_ps(a, b), _mm_castsi128_ps(hi));
p = _mm_hadd_ps(p, p);
p = _mm_hadd_ps(p, p);
return _mm_and_ps(p, _mm_castsi128_ps(lo));
}
__forceinline __m128 _mm_insert_ps(__m128 a, __m128 b, const int imm) {
float ta[4], tb[4];
_mm_storeu_ps(ta, a);
_mm_storeu_ps(tb, b);
ta[(imm >> 4) & 3] = tb[(imm >> 6) & 3];
for (int i = 0; i < 4; i++) if (imm & (1 << i)) ta[i] = 0.0f;
return _mm_loadu_ps(ta);
}
#define _MM_MASK_DENORM 0x0100
#define _MM_MASK_DIV_ZERO 0x0200
#define _MM_MASK_MASK 0x1f80
#define _MM_FLUSH_ZERO_MASK 0x8000
#define _MM_FLUSH_ZERO_ON 0x8000
#define _MM_SET_EXCEPTION_MASK(x) _mm_setcsr((_mm_getcsr() & ~_MM_MASK_MASK) | (x))
#define _MM_SET_FLUSH_ZERO_MODE(x) _mm_setcsr((_mm_getcsr() & ~_MM_FLUSH_ZERO_MASK) | (x))
#endif
#if defined(__EMSCRIPTEN__)
#include "../simd/wasm/emulation.h"
#endif
Expand Down
8 changes: 7 additions & 1 deletion common/sys/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,18 @@
#define __X86_ASM__
#endif

#if defined(__powerpc64__)
#define NO_WARN_X86_INTRINSICS
#define __SSE__ 1
#define __SSE2__ 1
#endif

/* detect 64 bit platform */
#if defined(__aarch64__) || defined(_M_ARM64)
#define EMBREE_ARM64
#endif

#if defined(__X86_64__) || defined(EMBREE_ARM64)
#if defined(__X86_64__) || defined(EMBREE_ARM64) || defined(__powerpc64__)
#define __64BIT__
#endif

Expand Down
7 changes: 7 additions & 0 deletions common/sys/sysinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,13 @@ namespace embree
#endif
return cpu_features;

#elif defined(__powerpc64__)

int cpu_features = CPU_FEATURE_SSE|CPU_FEATURE_SSE2|CPU_FEATURE_SSE3|CPU_FEATURE_SSSE3;
cpu_features |= CPU_FEATURE_SSE41|CPU_FEATURE_SSE42|CPU_FEATURE_POPCNT;
cpu_features |= CPU_FEATURE_XMM_ENABLED;
return cpu_features;

#elif defined(__ARM_NEON) || defined(EMBREE_ARM64) || defined(__EMSCRIPTEN__)

int cpu_features = CPU_FEATURE_NEON|CPU_FEATURE_SSE|CPU_FEATURE_SSE2;
Expand Down