ADDED src/forwarding/forwarding-powerpc64-elf.S Index: src/forwarding/forwarding-powerpc64-elf.S ================================================================== --- /dev/null +++ src/forwarding/forwarding-powerpc64-elf.S @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2008-2024 Jonathan Schleifer + * + * All rights reserved. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License version 3.0 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3.0 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3.0 along with this program. If not, see + * . + */ + +#include "config.h" + +#include "platform.h" + +.abiversion 2 + +.globl OFForward +.globl OFForward_stret + +.section .text +OFForward: + .cfi_startproc + addis %r2, %r12, .TOC.-OFForward@ha + addi %r2, %r2, .TOC.-OFForward@l +.localentry OFForward, .-OFForward + mflr %r0 + std %r0, 16(%r1) + stdu %r1, -160(%r1) + .cfi_def_cfa_offset 160 + .cfi_offset lr, 16 + std %r2, 24(%r1) + + /* Save all arguments */ + std %r3, 32(%r1) + std %r4, 40(%r1) + std %r5, 48(%r1) + std %r6, 56(%r1) + std %r7, 64(%r1) + std %r8, 72(%r1) + std %r9, 80(%r1) + std %r10, 88(%r1) + + /* Save all floating point arguments */ + stfd %f1, 96(%r1) + stfd %f2, 104(%r1) + stfd %f3, 112(%r1) + stfd %f4, 120(%r1) + stfd %f5, 128(%r1) + stfd %f6, 136(%r1) + stfd %f7, 144(%r1) + stfd %f8, 152(%r1) + + bl object_getClass + nop + + addis %r4, %r2, .Lsel_forwardingTargetForSelector_@toc@ha + addi %r4, %r4, .Lsel_forwardingTargetForSelector_@toc@l + bl class_respondsToSelector + nop + + cmpdi %r3, 0 + beq- 0f + + ld %r3, 32(%r1) + addis %r4, %r2, .Lsel_forwardingTargetForSelector_@toc@ha + addi %r4, %r4, .Lsel_forwardingTargetForSelector_@toc@l + bl objc_msg_lookup + nop + mr %r12, %r3 + + ld %r3, 32(%r1) + addis %r4, %r2, .Lsel_forwardingTargetForSelector_@toc@ha + addi %r4, %r4, .Lsel_forwardingTargetForSelector_@toc@l + ld %r5, 40(%r1) + mtctr %r12 + bctrl + ld %r2, 24(%r1) + + cmpdi %r3, 0 + beq- 0f + ld %r4, 32(%r1) + cmpw %r3, %r4 + beq- 0f + + std %r3, 32(%r1) + + ld %r4, 40(%r1) + bl objc_msg_lookup + nop + mr %r12, %r3 + + /* Restore all arguments */ + ld %r3, 32(%r1) + ld %r4, 40(%r1) + ld %r5, 48(%r1) + ld %r6, 56(%r1) + ld %r7, 64(%r1) + ld %r8, 72(%r1) + ld %r9, 80(%r1) + ld %r10, 88(%r1) + + /* Restore all floating point arguments */ + lfd %f1, 96(%r1) + lfd %f2, 104(%r1) + lfd %f3, 112(%r1) + lfd %f4, 120(%r1) + lfd %f5, 128(%r1) + lfd %f6, 136(%r1) + lfd %f7, 144(%r1) + lfd %f8, 152(%r1) + + addi %r1, %r1, 160 + ld %r0, 16(%r1) + mtlr %r0 + + mtctr %r12 + bctr + +0: + ld %r3, 32(%r1) + ld %r4, 40(%r1) + + bl OFMethodNotFound + nop + + addi %r1, %r1, 160 + lwz %r0, 16(%r1) + mtlr %r0 + + blr + .cfi_endproc +.type OFForward, @function +.size OFForward, .-OFForward + +OFForward_stret: + .cfi_startproc + addis %r2, %r12, .TOC.-OFForward_stret@ha + addi %r2, %r2, .TOC.-OFForward_stret@l +.localentry OFForward_stret, .-OFForward_stret + mflr %r0 + std %r0, 16(%r1) + stdu %r1, -160(%r1) + .cfi_def_cfa_offset 160 + .cfi_offset lr, 16 + std %r2, 24(%r1) + + /* Save all arguments */ + std %r3, 32(%r1) + std %r4, 40(%r1) + std %r5, 48(%r1) + std %r6, 56(%r1) + std %r7, 64(%r1) + std %r8, 72(%r1) + std %r9, 80(%r1) + std %r10, 88(%r1) + + /* Save all floating point arguments */ + stfd %f1, 96(%r1) + stfd %f2, 104(%r1) + stfd %f3, 112(%r1) + stfd %f4, 120(%r1) + stfd %f5, 128(%r1) + stfd %f6, 136(%r1) + stfd %f7, 144(%r1) + stfd %f8, 152(%r1) + + mr %r3, %r4 + bl object_getClass + nop + + addis %r4, %r2, .Lsel_forwardingTargetForSelector_@toc@ha + addi %r4, %r4, .Lsel_forwardingTargetForSelector_@toc@l + bl class_respondsToSelector + nop + + cmpdi %r3, 0 + beq- 0f + + ld %r3, 40(%r1) + addis %r4, %r2, .Lsel_forwardingTargetForSelector_@toc@ha + addi %r4, %r4, .Lsel_forwardingTargetForSelector_@toc@l + bl objc_msg_lookup + nop + mr %r12, %r3 + + ld %r3, 40(%r1) + addis %r4, %r2, .Lsel_forwardingTargetForSelector_@toc@ha + addi %r4, %r4, .Lsel_forwardingTargetForSelector_@toc@l + ld %r5, 48(%r1) + mtctr %r12 + bctrl + ld %r2, 24(%r1) + + cmpdi %r3, 0 + beq- 0f + ld %r4, 40(%r1) + cmpw %r3, %r4 + beq- 0f + + std %r3, 40(%r1) + + ld %r4, 48(%r1) + bl objc_msg_lookup_stret + nop + mr %r12, %r3 + + /* Restore all arguments */ + ld %r3, 32(%r1) + ld %r4, 40(%r1) + ld %r5, 48(%r1) + ld %r6, 56(%r1) + ld %r7, 64(%r1) + ld %r8, 72(%r1) + ld %r9, 80(%r1) + ld %r10, 88(%r1) + + /* Restore all floating point arguments */ + lfd %f1, 96(%r1) + lfd %f2, 104(%r1) + lfd %f3, 112(%r1) + lfd %f4, 120(%r1) + lfd %f5, 128(%r1) + lfd %f6, 136(%r1) + lfd %f7, 144(%r1) + lfd %f8, 152(%r1) + + addi %r1, %r1, 160 + ld %r0, 16(%r1) + mtlr %r0 + + mtctr %r12 + bctr + +0: + ld %r3, 32(%r1) + ld %r4, 40(%r1) + ld %r5, 48(%r1) + + bl OFMethodNotFound_stret + nop + + addi %r1, %r1, 160 + lwz %r0, 16(%r1) + mtlr %r0 + + blr + .cfi_endproc +.type OFForward_stret, @function +.size OFForward_stret, .-OFForward_stret + +.Linit: + addis %r2, %r12, .TOC.-.Linit@ha + addi %r2, %r2, .TOC.-.Linit@l +.localentry .Linit, .-.Linit + mflr %r0 + std %r0, 16(%r1) + stdu %r1, -32(%r1) + + addis %r3, %r2, .Lmodule@toc@ha + addi %r3, %r3, .Lmodule@toc@l + bl __objc_exec_class + nop + + addi %r1, %r1, 32 + ld %r0, 16(%r1) + + mtlr %r0 + blr + +.section .ctors, "aw", @progbits + .quad .Linit + +.section .rodata +.Lstr_forwardingTargetForSelector_: + .asciz "forwardingTargetForSelector:" + +.section .data +.Lsel_forwardingTargetForSelector_: + .quad .Lstr_forwardingTargetForSelector_, 0 + .quad 0, 0 +.Lsymtab: + .quad 0, .Lsel_forwardingTargetForSelector_ + .short 0, 0 + .long 0 + .quad 0 +.Lmodule: + .quad 8, 32, 0, .Lsymtab + +#if defined(OF_LINUX) || defined(OF_HAIKU) || defined(OF_HURD) +.section .note.GNU-stack, "", @progbits +#endif Index: src/forwarding/forwarding.S ================================================================== --- src/forwarding/forwarding.S +++ src/forwarding/forwarding.S @@ -43,10 +43,12 @@ # include "forwarding-arm64-elf.S" # elif defined(OF_ARM) # include "forwarding-arm-elf.S" # elif defined(OF_POWERPC) # include "forwarding-powerpc-elf.S" +# elif defined(OF_POWERPC64) && defined(_CALL_ELF) && _CALL_ELF == 2 +# include "forwarding-powerpc64-elf.S" # elif defined(OF_MIPS64_N64) # include "forwarding-mips64-n64-elf.S" # elif defined(OF_MIPS) # include "forwarding-mips-elf.S" # elif defined(OF_SPARC64) Index: src/macros.h ================================================================== --- src/macros.h +++ src/macros.h @@ -347,11 +347,12 @@ # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET # endif #else # if defined(OF_ELF) # if defined(OF_AMD64) || defined(OF_X86) || \ - defined(OF_ARM64) || defined(OF_ARM) || defined(OF_POWERPC) || \ + defined(OF_ARM64) || defined(OF_ARM) || \ + defined(OF_POWERPC) || defined(OF_POWERPC64) || \ defined(OF_MIPS64_N64) || defined(OF_MIPS) || \ defined(OF_SPARC64) || defined(OF_SPARC) || \ defined(OF_RISCV64) || defined(OF_LOONGARCH64) # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR # if __OBJFW_RUNTIME_ABI__ >= 800