Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PowerPC {32, 64}-bit Block Trampolines #272

Merged
merged 41 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
3664b7d
Implement PowerPC block trampoline
hmelder Jan 20, 2024
ea9b9f4
Adjust indentation
hmelder Jan 20, 2024
22e737c
PowerPC64 Linux has a different pagesize by default
hmelder Jan 20, 2024
8379d09
Temporary page size workaround
hmelder Jan 20, 2024
c4d6a5d
Fix lwz offset in PowerPC block trampoline
hmelder Jan 20, 2024
2db13a5
Adjust LOAD instruction PowerPC 32-bit to lwz
hmelder Jan 20, 2024
444c54e
Adjust pagesize on ppc64
hmelder Jan 20, 2024
0958563
Skip UnexpectedException test for PowerPC
hmelder Jan 20, 2024
ac06f53
Move PAGE_SIZE to asmconstants.h
hmelder Jan 21, 2024
c3cc4e9
Use PAGE_SIZE and PAGE_SHIFT macros for PowerPC
hmelder Jan 21, 2024
e088997
Add trailing newline to asmconstants.h
hmelder Jan 21, 2024
bf7ed5b
Add ppc64el and powerpc qemu-crossbuild targets
hmelder Jan 21, 2024
6ab3c5c
Use correct linker
hmelder Jan 21, 2024
9c4872f
Restrict LD_LIBRARY_PATH and link with atomic
hmelder Jan 21, 2024
53b418e
Remove powerpc arch
hmelder Jan 21, 2024
39a3776
Link with libatomic on PowerPC
hmelder Jan 21, 2024
1f925a5
Add powerpc and powerpc64 to detect_arch.c
hmelder Jan 21, 2024
c26e311
Update asmconstants.h
hmelder Jan 22, 2024
7317013
Implement PowerPC block trampoline
hmelder Jan 20, 2024
7ef1349
Adjust indentation
hmelder Jan 20, 2024
b16cbb5
PowerPC64 Linux has a different pagesize by default
hmelder Jan 20, 2024
a9e7fb6
Temporary page size workaround
hmelder Jan 20, 2024
ff25ce2
Fix lwz offset in PowerPC block trampoline
hmelder Jan 20, 2024
af49d8a
Adjust LOAD instruction PowerPC 32-bit to lwz
hmelder Jan 20, 2024
43477c6
Adjust pagesize on ppc64
hmelder Jan 20, 2024
6358f57
Skip UnexpectedException test for PowerPC
hmelder Jan 20, 2024
15c25d9
Move PAGE_SIZE to asmconstants.h
hmelder Jan 21, 2024
eb7e688
Use PAGE_SIZE and PAGE_SHIFT macros for PowerPC
hmelder Jan 21, 2024
b432464
Add trailing newline to asmconstants.h
hmelder Jan 21, 2024
c47bf6a
Add ppc64el and powerpc qemu-crossbuild targets
hmelder Jan 21, 2024
1496103
Use correct linker
hmelder Jan 21, 2024
68334c9
Restrict LD_LIBRARY_PATH and link with atomic
hmelder Jan 21, 2024
bb46b6c
Remove powerpc arch
hmelder Jan 21, 2024
4124c3b
Link with libatomic on PowerPC
hmelder Jan 21, 2024
da39edb
Add powerpc and powerpc64 to detect_arch.c
hmelder Jan 21, 2024
ef781fd
Update asmconstants.h
hmelder Jan 22, 2024
62b6676
Merge branch 'ppc-block-trampoline' of ssh://github.com/gnustep/libob…
hmelder Feb 12, 2024
0815f3d
Add NO_SAFE_CACHING definition and guards
hmelder Feb 12, 2024
0750a99
Do not export objc_method_cache_version on ppc32
hmelder Feb 12, 2024
c7eb3c0
Check if version ptr is valid before writing to it
hmelder Feb 12, 2024
62fe4b7
Merge branch 'master' into ppc-block-trampoline
hmelder Feb 12, 2024
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
6 changes: 5 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 }} \
Expand Down
4 changes: 4 additions & 0 deletions CMake/detect_arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,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")
Expand Down Expand Up @@ -244,6 +244,10 @@ if (WIN32 AND NOT MINGW)
target_link_libraries(objc ntdll.dll)
endif()

if (ARCHITECTURE STREQUAL "powerpc")
target_link_libraries(objc atomic)
endif()

target_link_libraries(objc tsl::robin_map)

set_target_properties(objc PROPERTIES
Expand Down
2 changes: 1 addition & 1 deletion Test/UnexpectedException.m
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 9 additions & 0 deletions asmconstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,12 @@
#define SLOT_OFFSET 0
#endif
#define SMALLOBJ_MASK ((1<<SMALLOBJ_BITS) - 1)

// Page size configuration
#if defined(__powerpc64__)
#define PAGE_SIZE 65536
#define PAGE_SHIFT 16
#else
#define PAGE_SIZE 4096
#define PAGE_SHIFT 12
#endif
hmelder marked this conversation as resolved.
Show resolved Hide resolved
15 changes: 10 additions & 5 deletions block_to_imp.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "blocks_runtime.h"
#include "lock.h"
#include "visibility.h"
#include "asmconstants.h" // For PAGE_SIZE

#ifndef __has_builtin
#define __has_builtin(x) 0
Expand Down Expand Up @@ -95,22 +96,26 @@ static int mprotect(void *buffer, size_t len, int prot)
# endif
#endif

#define PAGE_SIZE 4096

struct block_header
{
void *block;
void(*fnptr)(void);
/**
* On 64-bit platforms, we have 16 bytes for instructions, which ought to
* be enough without padding. On MIPS, we need
* be enough without padding.
* Note: If we add too much padding, then we waste space but have no other
* ill effects. If we get this too small, then the assert in
* `init_trampolines` will fire on library load.
*
* PowerPC: We need INSTR_CNT * INSTR_LEN = 7*4 = 28 bytes
* for instruction. sizeof(block_header) must be a divisor of
* PAGE_SIZE, so we need to pad block_header to 32 bytes.
* On PowerPC 64-bit where sizeof(void *) = 8 bytes, we
* add 16 bytes of padding.
*/
#if defined(__i386__) || (defined(__mips__) && !defined(__mips_n64))
#if defined(__i386__) || (defined(__mips__) && !defined(__mips_n64)) || (defined(__powerpc__) && !defined(__powerpc64__))
uint64_t padding[3];
#elif defined(__mips__)
#elif defined(__mips__) || defined(__powerpc64__)
uint64_t padding[2];
#elif defined(__arm__)
uint64_t padding;
Expand Down
40 changes: 40 additions & 0 deletions block_trampolines.S
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "common.S"
#include "asmconstants.h"

#
# This file defines some trampolines for calling blocks. A block function
Expand Down Expand Up @@ -98,6 +99,45 @@
#define ARG1 $a1
#define ARG2 $a2

#elif defined(__powerpc__)
////////////////////////////////////////////////////////////////////////////////
// PowerPC trampoline
////////////////////////////////////////////////////////////////////////////////

#if defined(__powerpc64__)
#define LOAD ld
#define OFFSET 8
#else
#define LOAD lwz
#define OFFSET 4
#endif

.macro trampoline arg0, arg1
mfctr %r12 # The block trampoline is always called
# via a function pointer. We can thus
# assume that ctr contains the trampline
# entry point address from the previous
# branch to this trampoline (bctrl).

#if PAGE_SHIFT < 16
addi %r12, %r12, -PAGE_SIZE # Substract page size from entry point
#else
addis %r12, %r12, (-0x1 << (PAGE_SHIFT - 16))
#endif

mr \arg1, \arg0
LOAD \arg0, 0(%r12)
LOAD %r12, OFFSET(%r12)
mtctr %r12 # Move block function pointer into ctr
bctr # Branch to block function
.endm

#define ARG0 %r3
#define ARG1 %r4
#define ARG2 %r5
#define SARG0 ARG1
#define SARG1 ARG2

#elif defined(__riscv) && (__riscv_xlen == 64)
////////////////////////////////////////////////////////////////////////////////
// RISC-V trampoline
Expand Down