From cf3303018e4e58d6be84b7ac37b9c85f21f96dd9 Mon Sep 17 00:00:00 2001 From: Ioannis Tsakpinis Date: Thu, 9 Nov 2023 19:04:23 +0200 Subject: [PATCH] build: add support for Linux PowerPC 64 LE Close #495 --- .github/workflows/build.yml | 8 +- README.md | 1 + build.gradle.kts | 9 +- build.xml | 28 +++ config/build-definitions.xml | 12 +- config/linux/build.xml | 28 +-- doc/notes/3.3.4.md | 4 +- .../src/main/c/libffi/ppc64le/ffitarget.h | 233 ++++++++++++++++++ .../src/main/c/libffi/riscv64/ffitarget.h | 1 + .../main/java/org/lwjgl/system/Platform.java | 6 + modules/lwjgl/rpmalloc/src/main/c/rpmalloc.c | 8 +- 11 files changed, 309 insertions(+), 29 deletions(-) create mode 100644 modules/lwjgl/core/src/main/c/libffi/ppc64le/ffitarget.h diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a464433635..752153feec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -132,7 +132,7 @@ jobs: strategy: fail-fast: false matrix: - ARCH: [arm32, arm64, riscv64] + ARCH: [arm32, arm64, ppc64le, riscv64] include: - ARCH: arm32 CROSS_ARCH: armhf @@ -142,6 +142,10 @@ jobs: CROSS_ARCH: arm64 CONTAINER: ubuntu:18.04 TRIPLET: aarch64-linux-gnu + - ARCH: ppc64le + CROSS_ARCH: ppc64el + CONTAINER: ubuntu:18.04 + TRIPLET: powerpc64le-linux-gnu - ARCH: riscv64 CROSS_ARCH: riscv64 CONTAINER: ubuntu:20.04 @@ -174,7 +178,7 @@ jobs: DEBIAN_FRONTEND=noninteractive apt-get -yq install ant awscli curl zstd gcc-${{matrix.TRIPLET}} g++-${{matrix.TRIPLET}} libc6-dev-${{matrix.CROSS_ARCH}}-cross mkdir jdk8 curl -L https://cdn.azul.com/zulu/bin/zulu8.72.0.17-ca-fx-jdk8.0.382-linux_x64.tar.gz | tar xz -C jdk8 --strip-components 1 - - name: Prepare cross-compilation for $${matrix.CROSS_ARCH}} + - name: Prepare cross-compilation for ${{matrix.CROSS_ARCH}} run: | sed -i 's/deb http/deb [arch=amd64,i386] http/' /etc/apt/sources.list grep "ubuntu.com/ubuntu" /etc/apt/sources.list | tee /etc/apt/sources.list.d/ports.list diff --git a/README.md b/README.md index fdab7c8aa5..3848823631 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ following platforms/architectures: - Linux x64 - Linux arm64 (ARMv8/AArch64) - Linux arm32 (ARMv7/armhf) +- Linux ppc64le - Linux riscv64 - macOS x64 - macOS arm64 diff --git a/build.gradle.kts b/build.gradle.kts index 7f74613743..62df1c30b3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -62,6 +62,7 @@ enum class Platforms(val classifier: String) { LINUX("linux"), LINUX_ARM64("linux-arm64"), LINUX_ARM32("linux-arm32"), + LINUX_PPC64LE("linux-ppc64le"), LINUX_RISCV64("linux-riscv64"), MACOS("macos"), MACOS_ARM64("macos-arm64"), @@ -89,7 +90,7 @@ enum class Artifacts( BGFX( "lwjgl-bgfx", "LWJGL - bgfx bindings", "A cross-platform, graphics API agnostic rendering library. It provides a high performance, low level abstraction for common platform graphics APIs like OpenGL, Direct3D and Apple Metal.", - Platforms.LINUX, Platforms.LINUX_ARM64, Platforms.LINUX_ARM32, Platforms.LINUX_RISCV64, + Platforms.LINUX, Platforms.LINUX_ARM64, Platforms.LINUX_ARM32, Platforms.LINUX_PPC64LE, Platforms.LINUX_RISCV64, Platforms.MACOS, Platforms.MACOS_ARM64, Platforms.WINDOWS, Platforms.WINDOWS_X86 ), @@ -137,7 +138,7 @@ enum class Artifacts( KTX( "lwjgl-ktx", "LWJGL - KTX (Khronos Texture) bindings", "A lightweight container for textures for OpenGL®, Vulkan® and other GPU APIs.", - Platforms.LINUX, Platforms.LINUX_ARM64, Platforms.LINUX_ARM32, Platforms.LINUX_RISCV64, + Platforms.LINUX, Platforms.LINUX_ARM64, Platforms.LINUX_ARM32, Platforms.LINUX_PPC64LE, Platforms.LINUX_RISCV64, Platforms.MACOS, Platforms.MACOS_ARM64, Platforms.WINDOWS, Platforms.WINDOWS_ARM64 ), @@ -219,7 +220,7 @@ enum class Artifacts( OPENXR( "lwjgl-openxr", "LWJGL - OpenXR bindings", "A royalty-free, open standard that provides high-performance access to Augmented Reality (AR) and Virtual Reality (VR)—collectively known as XR—platforms and devices.", - Platforms.LINUX, Platforms.LINUX_ARM64, Platforms.LINUX_ARM32, Platforms.LINUX_RISCV64, + Platforms.LINUX, Platforms.LINUX_ARM64, Platforms.LINUX_ARM32, Platforms.LINUX_PPC64LE, Platforms.LINUX_RISCV64, Platforms.WINDOWS, Platforms.WINDOWS_X86, Platforms.WINDOWS_ARM64 ), OPUS( @@ -240,7 +241,7 @@ enum class Artifacts( REMOTERY( "lwjgl-remotery", "LWJGL - Remotery bindings", "A realtime CPU/GPU profiler hosted in a single C file with a viewer that runs in a web browser.", - Platforms.LINUX, Platforms.LINUX_ARM64, Platforms.LINUX_ARM32, Platforms.LINUX_RISCV64, + Platforms.LINUX, Platforms.LINUX_ARM64, Platforms.LINUX_ARM32, Platforms.LINUX_PPC64LE, Platforms.LINUX_RISCV64, Platforms.MACOS, Platforms.MACOS_ARM64, Platforms.WINDOWS, Platforms.WINDOWS_X86 ), diff --git a/build.xml b/build.xml index 968b1bf20a..2fc1d0e0f6 100644 --- a/build.xml +++ b/build.xml @@ -1177,6 +1177,7 @@ + @@ -1208,6 +1209,9 @@ + + + @@ -1278,6 +1282,9 @@ + + + @@ -1309,6 +1316,7 @@ + @@ -1337,6 +1345,7 @@ + @@ -1548,6 +1557,10 @@ + + + + @@ -1586,6 +1599,9 @@ + + + @@ -1627,6 +1643,9 @@ + + + @@ -1669,6 +1688,7 @@ + @@ -1714,6 +1734,7 @@ + @@ -1736,6 +1757,9 @@ + + + @@ -1798,6 +1822,9 @@ + + + @@ -1832,6 +1859,7 @@ + diff --git a/config/build-definitions.xml b/config/build-definitions.xml index 04a9ddbeaa..b73303b96c 100644 --- a/config/build-definitions.xml +++ b/config/build-definitions.xml @@ -34,6 +34,12 @@ This script is included in /build.xml and /config/update-dependencies.xml. + + + + + + @@ -43,6 +49,7 @@ This script is included in /build.xml and /config/update-dependencies.xml. + @@ -50,13 +57,14 @@ This script is included in /build.xml and /config/update-dependencies.xml. + - - + + diff --git a/config/linux/build.xml b/config/linux/build.xml index 3e2da924d9..6b759ffc59 100644 --- a/config/linux/build.xml +++ b/config/linux/build.xml @@ -5,12 +5,14 @@ - - - - - - + + + + + + + + @@ -39,6 +41,7 @@ + @@ -179,6 +182,7 @@ + @@ -265,12 +269,6 @@ - - - - - - @@ -289,12 +287,6 @@ - - - - - - diff --git a/doc/notes/3.3.4.md b/doc/notes/3.3.4.md index 3bacc3c066..9a3588c5c7 100644 --- a/doc/notes/3.3.4.md +++ b/doc/notes/3.3.4.md @@ -24,7 +24,9 @@ This build includes the following changes: #### Improvements -- Linux: Added support for the RISC-V 64 architecture. +- Linux: Added support for the PowerPC 64 LE architecture. (#495) + * Maven classifier: `linux-ppc64le` +- Linux: Added support for the RISC-V 64 architecture. (#890) * Maven classifier: `linux-riscv64` - Vulkan: Made `VkMemoryRequirements` mutable for the `vmaAllocateMemory(Pages)` functions. (#937) diff --git a/modules/lwjgl/core/src/main/c/libffi/ppc64le/ffitarget.h b/modules/lwjgl/core/src/main/c/libffi/ppc64le/ffitarget.h new file mode 100644 index 0000000000..bf6b2f1da9 --- /dev/null +++ b/modules/lwjgl/core/src/main/c/libffi/ppc64le/ffitarget.h @@ -0,0 +1,233 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc + Copyright (c) 1996-2003 Red Hat, Inc. + + Target configuration macros for PowerPC. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +/* ---- System specific configurations ----------------------------------- */ + +#if defined (POWERPC) && defined (__powerpc64__) /* linux64 */ +#ifndef POWERPC64 +#define POWERPC64 +#endif +#elif defined (POWERPC_DARWIN) && defined (__ppc64__) /* Darwin64 */ +#ifndef POWERPC64 +#define POWERPC64 +#endif +#ifndef POWERPC_DARWIN64 +#define POWERPC_DARWIN64 +#endif +#elif defined (POWERPC_AIX) && defined (__64BIT__) /* AIX64 */ +#ifndef POWERPC64 +#define POWERPC64 +#endif +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + +#if defined (POWERPC_AIX) + FFI_AIX, + FFI_DARWIN, + FFI_DEFAULT_ABI = FFI_AIX, + FFI_LAST_ABI + +#elif defined (POWERPC_DARWIN) + FFI_AIX, + FFI_DARWIN, + FFI_DEFAULT_ABI = FFI_DARWIN, + FFI_LAST_ABI + +#else + /* The FFI_COMPAT values are used by old code. Since libffi may be + a shared library we have to support old values for backwards + compatibility. */ + FFI_COMPAT_SYSV, + FFI_COMPAT_GCC_SYSV, + FFI_COMPAT_LINUX64, + FFI_COMPAT_LINUX, + FFI_COMPAT_LINUX_SOFT_FLOAT, + +# if defined (POWERPC64) + /* This bit, always set in new code, must not be set in any of the + old FFI_COMPAT values that might be used for 64-bit linux. We + only need worry about FFI_COMPAT_LINUX64, but to be safe avoid + all old values. */ + FFI_LINUX = 8, + /* This and following bits can reuse FFI_COMPAT values. */ + FFI_LINUX_STRUCT_ALIGN = 1, + FFI_LINUX_LONG_DOUBLE_128 = 2, + FFI_LINUX_LONG_DOUBLE_IEEE128 = 4, + FFI_DEFAULT_ABI = (FFI_LINUX +# ifdef __STRUCT_PARM_ALIGN__ + | FFI_LINUX_STRUCT_ALIGN +# endif +# ifdef __LONG_DOUBLE_128__ + | FFI_LINUX_LONG_DOUBLE_128 +# ifdef __LONG_DOUBLE_IEEE128__ + | FFI_LINUX_LONG_DOUBLE_IEEE128 +# endif +# endif + ), + FFI_LAST_ABI = 16, + +// LWJGL + FFI_WIN64 = -1, + FFI_GNUW64 = -1, + FFI_UNIX64 = -1, + FFI_EFI64 = -1, + FFI_SYSV = -1, + FFI_STDCALL = -1, + FFI_THISCALL = -1, + FFI_FASTCALL = -1, + FFI_MS_CDECL = -1, + FFI_PASCAL = -1, + FFI_REGISTER = -1, + FFI_VFP = -1 + +# else + /* This bit, always set in new code, must not be set in any of the + old FFI_COMPAT values that might be used for 32-bit linux/sysv/bsd. */ + FFI_SYSV = 8, + /* This and following bits can reuse FFI_COMPAT values. */ + FFI_SYSV_SOFT_FLOAT = 1, + FFI_SYSV_STRUCT_RET = 2, + FFI_SYSV_IBM_LONG_DOUBLE = 4, + FFI_SYSV_LONG_DOUBLE_128 = 16, + + FFI_DEFAULT_ABI = (FFI_SYSV +# ifdef __NO_FPRS__ + | FFI_SYSV_SOFT_FLOAT +# endif +# if (defined (__SVR4_STRUCT_RETURN) \ + || defined (POWERPC_FREEBSD) && !defined (__AIX_STRUCT_RETURN)) + | FFI_SYSV_STRUCT_RET +# endif +# if __LDBL_MANT_DIG__ == 106 + | FFI_SYSV_IBM_LONG_DOUBLE +# endif +# ifdef __LONG_DOUBLE_128__ + | FFI_SYSV_LONG_DOUBLE_128 +# endif + ), + FFI_LAST_ABI = 32, + +// LWJGL + FFI_WIN64 = -1, + FFI_GNUW64 = -1, + FFI_UNIX64 = -1, + FFI_EFI64 = -1, +// FFI_SYSV = -1, + FFI_STDCALL = -1, + FFI_THISCALL = -1, + FFI_FASTCALL = -1, + FFI_MS_CDECL = -1, + FFI_PASCAL = -1, + FFI_REGISTER = -1, + FFI_VFP = -1 + +# endif +#endif + +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_NATIVE_RAW_API 0 +#if defined (POWERPC) || defined (POWERPC_FREEBSD) +# define FFI_GO_CLOSURES 1 +# define FFI_TARGET_SPECIFIC_VARIADIC 1 +# define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs +#endif +#if defined (POWERPC_AIX) +# define FFI_GO_CLOSURES 1 +#endif + +/* ppc_closure.S and linux64_closure.S expect this. */ +#define FFI_PPC_TYPE_LAST FFI_TYPE_POINTER + +/* We define additional types below. If generic types are added that + must be supported by powerpc libffi then it is likely that + FFI_PPC_TYPE_LAST needs increasing *and* the jump tables in + ppc_closure.S and linux64_closure.S be extended. */ + +#if !(FFI_TYPE_LAST == FFI_PPC_TYPE_LAST \ + || (FFI_TYPE_LAST == FFI_TYPE_COMPLEX \ + && !defined FFI_TARGET_HAS_COMPLEX_TYPE)) +# error "You likely have a broken powerpc libffi" +#endif + +/* Needed for soft-float long-double-128 support. */ +#define FFI_TYPE_UINT128 (FFI_PPC_TYPE_LAST + 1) + +/* Needed for FFI_SYSV small structure returns. */ +#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 2) + +/* Used by ELFv2 for homogenous structure returns. */ +#define FFI_V2_TYPE_VECTOR (FFI_PPC_TYPE_LAST + 1) +#define FFI_V2_TYPE_VECTOR_HOMOG (FFI_PPC_TYPE_LAST + 2) +#define FFI_V2_TYPE_FLOAT_HOMOG (FFI_PPC_TYPE_LAST + 3) +#define FFI_V2_TYPE_DOUBLE_HOMOG (FFI_PPC_TYPE_LAST + 4) +#define FFI_V2_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 5) + +#if _CALL_ELF == 2 +# define FFI_TRAMPOLINE_SIZE 32 +#else +# if defined(POWERPC64) || defined(POWERPC_AIX) +# if defined(POWERPC_DARWIN64) +# define FFI_TRAMPOLINE_SIZE 48 +# else +# define FFI_TRAMPOLINE_SIZE 24 +# endif +# else /* POWERPC || POWERPC_AIX */ +# define FFI_TRAMPOLINE_SIZE 40 +# endif +#endif + +#ifndef LIBFFI_ASM +#if defined(POWERPC_DARWIN) || defined(POWERPC_AIX) +struct ffi_aix_trampoline_struct { + void * code_pointer; /* Pointer to ffi_closure_ASM */ + void * toc; /* TOC */ + void * static_chain; /* Pointer to closure */ +}; +#endif +#endif + +#endif diff --git a/modules/lwjgl/core/src/main/c/libffi/riscv64/ffitarget.h b/modules/lwjgl/core/src/main/c/libffi/riscv64/ffitarget.h index bb7acc16bd..b934a7418d 100644 --- a/modules/lwjgl/core/src/main/c/libffi/riscv64/ffitarget.h +++ b/modules/lwjgl/core/src/main/c/libffi/riscv64/ffitarget.h @@ -52,6 +52,7 @@ typedef enum ffi_abi { FFI_LAST_ABI, FFI_DEFAULT_ABI = FFI_SYSV, + // LWJGL FFI_WIN64 = -1, FFI_GNUW64 = -1, diff --git a/modules/lwjgl/core/src/main/java/org/lwjgl/system/Platform.java b/modules/lwjgl/core/src/main/java/org/lwjgl/system/Platform.java index cca52a0586..127d1508b6 100644 --- a/modules/lwjgl/core/src/main/java/org/lwjgl/system/Platform.java +++ b/modules/lwjgl/core/src/main/java/org/lwjgl/system/Platform.java @@ -55,6 +55,7 @@ public enum Architecture { X86(false), ARM64(true), ARM32(false), + PPC64LE(true), RISCV64(true); static final Architecture current; @@ -67,6 +68,11 @@ public enum Architecture { if (osArch.startsWith("arm") || osArch.startsWith("aarch")) { current = is64Bit ? Architecture.ARM64 : Architecture.ARM32; + } else if (osArch.startsWith("ppc")) { + if (!"ppc64le".equals(osArch)) { + throw new UnsupportedOperationException("Only PowerPC 64 LE is supported."); + } + current = Architecture.PPC64LE; } else if (osArch.startsWith("riscv")) { if (!"riscv64".equals(osArch)) { throw new UnsupportedOperationException("Only RISC-V 64 is supported."); diff --git a/modules/lwjgl/rpmalloc/src/main/c/rpmalloc.c b/modules/lwjgl/rpmalloc/src/main/c/rpmalloc.c index 3172427219..dc06fde135 100644 --- a/modules/lwjgl/rpmalloc/src/main/c/rpmalloc.c +++ b/modules/lwjgl/rpmalloc/src/main/c/rpmalloc.c @@ -808,14 +808,18 @@ get_thread_id(void) { # else __asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tid)); # endif +# elif defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__) + // LWJGL + return (uintptr_t)((void*)gettid()); # elif defined(__riscv) + // LWJGL __asm__ volatile ("mv %0, tp" : "=r" (tid)); # else -# error This platform needs implementation of get_thread_id() +# error This platform needs implementation of get_thread_id() inner # endif return tid; #else -# error This platform needs implementation of get_thread_id() +# error This platform needs implementation of get_thread_id() outer #endif }