Skip to content

Commit

Permalink
PowerPC Little Endian 64-bit support (#1377)
Browse files Browse the repository at this point in the history
Co-authored-by: Jorrit Rouwe <[email protected]>
  • Loading branch information
Link4Electronics and jrouwe authored Dec 20, 2024
1 parent 7c3942d commit 9b3e9e6
Show file tree
Hide file tree
Showing 13 changed files with 79 additions and 14 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/determinism_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ env:
UBUNTU_GCC_VERSION: g++-12
UBUNTU_GCC_AARCH64_VERSION: aarch64-linux-gnu-g++-12
UBUNTU_GCC_RISCV_VERSION: riscv64-linux-gnu-g++-12
UBUNTU_GCC_POWERPC_VERSION: powerpc64le-linux-gnu-g++-12

on:
push:
Expand Down Expand Up @@ -264,6 +265,35 @@ jobs:
working-directory: ${{github.workspace}}/Build/Linux_Distribution
run: qemu-riscv64 -L /usr/riscv64-linux-gnu/ ./PerformanceTest -q=LinearCast -t=max -s=Pyramid -validate_hash=${PYRAMID_HASH}

powerpcle_gcc:
runs-on: ubuntu-latest
name: PowerPC Little Endian GCC Determinism Check
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Update index
run: sudo apt-get update
- name: Install Cross Compiler
run: sudo apt-get install g++-12-powerpc64le-linux-gnu gcc-12-multilib g++-12-multilib qemu-user -y
- name: Configure CMake
working-directory: ${{github.workspace}}/Build
run: ./cmake_linux_clang_gcc.sh Distribution ${{env.UBUNTU_GCC_POWERPC_VERSION}} -DCROSS_COMPILE_ARM=ON -DCROSS_PLATFORM_DETERMINISTIC=ON -DCROSS_COMPILE_ARM_TARGET="" -DTARGET_VIEWER=OFF -DTARGET_SAMPLES=OFF -DTARGET_HELLO_WORLD=OFF -DTARGET_UNIT_TESTS=ON -DTARGET_PERFORMANCE_TEST=ON
- name: Build
run: cmake --build ${{github.workspace}}/Build/Linux_Distribution -j $(nproc)
- name: Unit Tests
working-directory: ${{github.workspace}}/Build/Linux_Distribution
run: qemu-ppc64le -L /usr/powerpc64le-linux-gnu/ ./UnitTests
- name: Test ConvexVsMesh
working-directory: ${{github.workspace}}/Build/Linux_Distribution
run: qemu-ppc64le -L /usr/powerpc64le-linux-gnu/ ./PerformanceTest -q=LinearCast -t=max -s=ConvexVsMesh -validate_hash=${CONVEX_VS_MESH_HASH}
# This is really slow so disabled for the moment
# - name: Test Ragdoll
# working-directory: ${{github.workspace}}/Build/Linux_Distribution
# run: qemu-ppc64le -L /usr/powerpc64le-linux-gnu/ ./PerformanceTest -q=LinearCast -t=max -s=Ragdoll -validate_hash=${RAGDOLL_HASH}
# - name: Test Pyramid
# working-directory: ${{github.workspace}}/Build/Linux_Distribution
# run: qemu-ppc64le -L /usr/powerpc64le-linux-gnu/ ./PerformanceTest -q=LinearCast -t=max -s=Pyramid -validate_hash=${PYRAMID_HASH}

emscripten:
runs-on: ubuntu-latest
name: Emscripten Determinism Check
Expand Down
1 change: 1 addition & 0 deletions Docs/Architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ It is quite difficult to verify cross platform determinism, so this feature is l
* Linux gcc x86 64-bit with AVX2
* Linux gcc ARM 64-bit with NEON
* Linux gcc RISC-V 64-bit
* Linux gcc PowerPC (Little Endian) 64-bit
* WASM emscripten running in nodejs

The most important things to look out for in your own application:
Expand Down
2 changes: 1 addition & 1 deletion Docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ For breaking API changes see [this document](https://github.com/jrouwe/JoltPhysi
* Added `PhysicsSystem::SetSimShapeFilter`. This allows filtering out collisions between sub shapes within a body and can for example be used to have a single body that contains a low detail simulation shape an a high detail collision query shape.
* Added an example of a body that's both a sensor and a rigid body in `ContactListenerTest`.
* Added binary serialization to `SkeletalAnimation`.
* Added support for RISC-V CPUs.
* Added support for RISC-V and PowerPC (Little Endian) CPUs.

### Bug fixes

Expand Down
7 changes: 7 additions & 0 deletions Jolt/ConfigurationString.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ inline const char *GetConfigurationString()
"ARM "
#elif defined(JPH_CPU_RISCV)
"RISC-V "
#elif defined(JPH_CPU_PPC)
"PowerPC "
#ifdef JPH_CPU_BIG_ENDIAN
"(Big Endian) "
#else
"(Little Endian) "
#endif
#elif defined(JPH_CPU_E2K)
"E2K "
#elif defined(JPH_CPU_WASM)
Expand Down
21 changes: 20 additions & 1 deletion Jolt/Core/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,19 @@
#define JPH_USE_SSE4_1
#define JPH_USE_SSE4_2
#endif
#elif defined(__powerpc__) || defined(__powerpc64__)
// PowerPC CPU architecture
#define JPH_CPU_PPC
#if defined(__powerpc64__)
#define JPH_CPU_ADDRESS_BITS 64
#else
#define JPH_CPU_ADDRESS_BITS 32
#endif
#ifdef _BIG_ENDIAN
#define JPH_CPU_BIG_ENDIAN
#endif
#define JPH_VECTOR_ALIGNMENT 16
#define JPH_DVECTOR_ALIGNMENT 8
#elif defined(__e2k__)
// E2K CPU architecture (MCST Elbrus 2000)
#define JPH_CPU_E2K
Expand All @@ -224,6 +237,11 @@
#else
#define JPH_IF_RISCV(x)
#endif
#ifdef JPH_CPU_PPC
#define JPH_IF_PPC(x) x
#else
#define JPH_IF_PPC(x)
#endif

// If this define is set, Jolt is compiled as a shared library
#ifdef JPH_SHARED_LIBRARY
Expand Down Expand Up @@ -340,6 +358,7 @@
JPH_GCC_SUPPRESS_WARNING("-Wunused-parameter") \
JPH_GCC_SUPPRESS_WARNING("-Wmaybe-uninitialized") \
JPH_IF_RISCV(JPH_GCC_SUPPRESS_WARNING("-Wuninitialized")) \
JPH_IF_PPC(JPH_GCC_SUPPRESS_WARNING("-Wuninitialized")) \
\
JPH_MSVC_SUPPRESS_WARNING(4619) /* #pragma warning: there is no warning number 'XXXX' */ \
JPH_MSVC_SUPPRESS_WARNING(4514) /* 'X' : unreferenced inline function has been removed */ \
Expand Down Expand Up @@ -378,7 +397,7 @@
#elif defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID) || defined(JPH_PLATFORM_MACOS) || defined(JPH_PLATFORM_IOS) || defined(JPH_PLATFORM_FREEBSD)
#if defined(JPH_CPU_X86)
#define JPH_BREAKPOINT __asm volatile ("int $0x3")
#elif defined(JPH_CPU_ARM) || defined(JPH_CPU_RISCV) || defined(JPH_CPU_E2K)
#elif defined(JPH_CPU_ARM) || defined(JPH_CPU_RISCV) || defined(JPH_CPU_E2K) || defined(JPH_CPU_PPC)
#define JPH_BREAKPOINT __builtin_trap()
#else
#error Unknown CPU architecture
Expand Down
4 changes: 4 additions & 0 deletions Jolt/Core/FPControlWord.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ class FPControlWord : public NonCopyable

// RISC-V only implements manually checking if exceptions occurred by reading the fcsr register. It doesn't generate exceptions.

#elif defined(JPH_CPU_PPC)

// Not implemented right now

#else

#error Unsupported CPU architecture
Expand Down
4 changes: 4 additions & 0 deletions Jolt/Core/FPException.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ class FPExceptionDisableDivByZero : public FPControlWord<0, FP_DZE> { };

#error "RISC-V only implements manually checking if exceptions occurred by reading the fcsr register. It doesn't generate exceptions. JPH_FLOATING_POINT_EXCEPTIONS_ENABLED must be disabled."

#elif defined(JPH_CPU_PPC)

#error PowerPC floating point exception handling to be implemented. JPH_FLOATING_POINT_EXCEPTIONS_ENABLED must be disabled.

#else

#error Unsupported CPU architecture
Expand Down
2 changes: 1 addition & 1 deletion Jolt/Core/FPFlushDenormals.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

JPH_NAMESPACE_BEGIN

#if defined(JPH_CPU_WASM) || defined(JPH_CPU_RISCV)
#if defined(JPH_CPU_WASM) || defined(JPH_CPU_RISCV) || defined(JPH_CPU_PPC)

// Not supported
class FPFlushDenormals { };
Expand Down
2 changes: 1 addition & 1 deletion Jolt/Core/TickCounter.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ JPH_INLINE uint64 GetProcessorTickCount()
uint64 val;
asm volatile("mrs %0, cntvct_el0" : "=r" (val));
return val;
#elif defined(JPH_CPU_ARM) || defined(JPH_CPU_RISCV) || defined(JPH_CPU_WASM)
#elif defined(JPH_CPU_ARM) || defined(JPH_CPU_RISCV) || defined(JPH_CPU_WASM) || defined(JPH_CPU_PPC)
return 0; // Not supported
#else
#error Undefined
Expand Down
4 changes: 2 additions & 2 deletions Jolt/Math/Math.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ inline uint CountTrailingZeros(uint32 inValue)
return 32;
return __builtin_ctz(inValue);
#endif
#elif defined(JPH_CPU_E2K) || defined(JPH_CPU_RISCV)
#elif defined(JPH_CPU_E2K) || defined(JPH_CPU_RISCV) || defined(JPH_CPU_PPC)
return inValue ? __builtin_ctz(inValue) : 32;
#else
#error Undefined
Expand Down Expand Up @@ -150,7 +150,7 @@ inline uint CountLeadingZeros(uint32 inValue)
#else
return __builtin_clz(inValue);
#endif
#elif defined(JPH_CPU_E2K) || defined(JPH_CPU_RISCV)
#elif defined(JPH_CPU_E2K) || defined(JPH_CPU_RISCV) || defined(JPH_CPU_PPC)
return inValue ? __builtin_clz(inValue) : 32;
#else
#error Undefined
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Why create yet another physics engine? Firstly, it has been a personal learning
## Supported platforms

* Windows (Desktop or UWP) x86/x64/ARM32/ARM64
* Linux (tested on Ubuntu) x86/x64/ARM32/ARM64/RISC-V64
* Linux (tested on Ubuntu) x86/x64/ARM32/ARM64/RISC-V64/PowerPC64LE
* FreeBSD
* Android x86/x64/ARM32/ARM64
* Platform Blue (a popular game console) x64
Expand Down
2 changes: 1 addition & 1 deletion UnitTests/Core/FPFlushDenormalsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <Jolt/Core/FPFlushDenormals.h>
#include <atomic>

#if !defined(JPH_CPU_WASM) && !defined(JPH_CPU_RISCV)
#if !defined(JPH_CPU_WASM) && !defined(JPH_CPU_RISCV) && !defined(JPH_CPU_PPC)

// Implemented as a global atomic so the compiler can't optimize it to a constant
extern atomic<float> TestFltMin;
Expand Down
12 changes: 6 additions & 6 deletions UnitTests/Math/UVec4Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,17 +507,17 @@ TEST_SUITE("UVec4Tests")

TEST_CASE("TestUVec4ExtractUInt16")
{
uint16 ints[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
UVec4 vector = UVec4::sLoadInt4((const uint32 *)ints);
uint32 data[] = { 0x0b020a01, 0x0d040c03, 0x0b060a05, 0x0d080c07 };
UVec4 vector = UVec4::sLoadInt4(data);

CHECK(vector.Expand4Uint16Lo() == UVec4(1, 2, 3, 4));
CHECK(vector.Expand4Uint16Hi() == UVec4(5, 6, 7, 8));
CHECK(vector.Expand4Uint16Lo() == UVec4(0x0a01, 0x0b02, 0x0c03, 0x0d04));
CHECK(vector.Expand4Uint16Hi() == UVec4(0x0a05, 0x0b06, 0x0c07, 0x0d08));
}

TEST_CASE("TestUVec4ExtractBytes")
{
uint8 bytes[] = { 0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24, 0x31, 0x32, 0x33, 0x34, 0x41, 0x42, 0x43, 0x44 };
UVec4 vector = UVec4::sLoadInt4((const uint32 *)bytes);
uint32 data[] = { 0x14131211, 0x24232221, 0x34333231, 0x44434241 };
UVec4 vector = UVec4::sLoadInt4(data);

CHECK(vector.Expand4Byte0() == UVec4(0x11, 0x12, 0x13, 0x14));
CHECK(vector.Expand4Byte4() == UVec4(0x21, 0x22, 0x23, 0x24));
Expand Down

0 comments on commit 9b3e9e6

Please sign in to comment.