diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 41056eb0..4ed82300 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -88,6 +88,10 @@ jobs: system-processor: riscv64 triple: riscv64-linux-gnu rtld: ld-linux-riscv64-lp64d.so.1 + - name: ppc64el + system-processor: powerpc64le + triple: powerpc64le-linux-gnu + rtld: ld64.so.2 # lld versions prior to 15 do not support R_RISCV_ALIGN relocations exclude: - llvm-version: 13 @@ -108,7 +112,7 @@ jobs: sudo apt install libstdc++-9-dev-${{ matrix.arch.name }}-cross qemu-user ninja-build - name: Configure CMake run: | - export LDFLAGS="-L/usr/lib/llvm-${{ matrix.llvm-version }}/lib/ -fuse-ld=lld -Wl,--dynamic-linker=/usr/${{ matrix.arch.triple }}/lib/${{ matrix.arch.rtld }},-rpath,/usr/${{ matrix.arch.triple }}/lib" + export LDFLAGS="-L/usr/lib/llvm-${{ matrix.llvm-version }}/lib/ -fuse-ld=lld-${{ matrix.llvm-version}} -Wl,--dynamic-linker=/usr/${{ matrix.arch.triple }}/lib/${{ matrix.arch.rtld }},-rpath,/usr/${{ matrix.arch.triple }}/lib" cmake -B ${{github.workspace}}/build \ -DCMAKE_SYSTEM_NAME=Linux \ -DCMAKE_SYSTEM_PROCESSOR=${{ matrix.arch.system-processor }} \ diff --git a/CMake/detect_arch.c b/CMake/detect_arch.c index 3b9d3267..03df356e 100644 --- a/CMake/detect_arch.c +++ b/CMake/detect_arch.c @@ -7,6 +7,10 @@ #error i386 #elif defined(__x86_64__) #error x86_64 +#elif defined(__powerpc64__) +#error powerpc64 +#elif defined(__powerpc__) +#error powerpc #else #error unknown #endif \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f68b0144..748b1b84 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,7 @@ try_compile( ) if(NOT COMPILE_SUCCESS) - string(REGEX MATCH "(aarch64|arm|i386|x86_64|unknown)" ARCHITECTURE ${COMPILE_OUTPUT}) + string(REGEX MATCH "(aarch64|arm|i386|x86_64|powerpc64|powerpc|unknown)" ARCHITECTURE ${COMPILE_OUTPUT}) endif() set(ARCHITECTURE ${ARCHITECTURE} CACHE STRING "Architecture Type") @@ -187,6 +187,14 @@ set(INCLUDE_DIRECTORY "objc" CACHE STRING add_compile_options($<$:-march=i586>) +# PowerPC 32-bit does not support native 64-bit atomic operations, +# which is used in safe caching. +# You must also update the guard in objc/runtime.h, when updating +# this macro. +if (ARCHITECTURE STREQUAL "powerpc") + add_definitions(-DNO_SAFE_CACHING) +endif() + set(INSTALL_TARGETS objc) if(WIN32) diff --git a/Test/UnexpectedException.m b/Test/UnexpectedException.m index 10d210d4..9f2a2ba5 100644 --- a/Test/UnexpectedException.m +++ b/Test/UnexpectedException.m @@ -31,7 +31,7 @@ LONG WINAPI _UnhandledExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) int main(void) { -#if !(defined(__arm__) || defined(__ARM_ARCH_ISA_A64)) +#if !(defined(__arm__) || defined(__ARM_ARCH_ISA_A64)) && !defined(__powerpc__) #if defined(_WIN32) && !defined(__MINGW32__) // also verify that an existing handler still gets called after we set ours SetUnhandledExceptionFilter(&_UnhandledExceptionFilter); diff --git a/asmconstants.h b/asmconstants.h index d5f9559c..d15581c7 100644 --- a/asmconstants.h +++ b/asmconstants.h @@ -19,3 +19,11 @@ #define SLOT_OFFSET 0 #endif #define SMALLOBJ_MASK ((1<types) { @@ -350,10 +361,12 @@ struct objc_slot *objc_slot_lookup_super(struct objc_super *super, SEL selector) */ struct objc_slot2 *objc_get_slot2(Class cls, SEL selector, uint64_t *version) { +#ifndef NO_SAFE_CACHING if (version) { *version = objc_method_cache_version; } +#endif struct objc_slot2 * result = objc_dtable_lookup(cls->dtable, selector->index); if (0 == result) { @@ -374,10 +387,12 @@ struct objc_slot2 *objc_get_slot2(Class cls, SEL selector, uint64_t *version) { if ((result = objc_dtable_lookup(dtable, get_untyped_idx(selector)))) { +#ifndef NO_SAFE_CACHING if (version) { *version = 0; } +#endif uncacheable_slot.imp = call_mismatch_hook(cls, selector, result); result = (struct objc_slot2*)&uncacheable_slot; }