Sunday, October 10, 2021

lang/gcc/11 fix dlang fibers, unbreak powerpc64

import core.thread.fiber;
import std.algorithm;
import std.range;
import std.stdio;

// Make an integer sequence a, b, a + b + c, ...
int delegate() adder(int a, int b, int c) {
int next;
void yield(int i) {
next = i;
Fiber.yield();
}
auto fib = new Fiber({
writefln("adder(%d, %d, %d)()", a, b, c);
yield(a);
yield(b);
for (;;) {
yield(next = a + b + c);
a = b;
b = next;
}
});
return {fib.call(); return next;};
}

// Show the first 15 Leonardo numbers.
void main()
{
auto leonardo = adder(1, 1, 1);
writefln("%(%d, %)", iota(1, 15).map!(i => leonardo()));
}
Hello,

This diff unbreaks lang/gcc/11 on powerpc64, adds dlang to powerpc64,
and changes D's fibers on all archs; ok to commit?

gcc 11 was broken in powerpc64 bulks,
http://build-failures.rhaalovely.net/powerpc64/2021-09-27/lang/gcc/11,-c++.log

Unbreak by adding gnu-user.h (patch-gcc_config_gcc). Also add
PFRAG.powerpc64-main, to be like other archs; this PFRAG is still
missing in gcc 8. The rest of this diff is for the D programming
language, with parts for powerpc64, 32-bit powerpc, and all archs.

Add powerpc64 to ONLY_FOR_ARCHS-dlang. Add enough PPC64 code to
libphobos to complete the build. (I might be the 1st person to try D
on powerpc64.) This PPC64 code is trivial, except the code for fibers
(https://tour.dlang.org/tour/en/multithreading/fibers), where I wrote
some powerpc64 asm. I found 2 other problems with fibers:

1. The fiber crashed SIGSEGV, because it didn't pass MAP_STACK to
mmap(2). The fix is easy, and affects all archs.

2. The existing code for 32-bit powerpc was wrong; it saved the
link register at 8(%r1), should be 4(%r1), and allowed signal
handlers to clobber the values saved below %r1. I change
almost every line of 32-bit asm as I add the 64-bit asm.

The attachment "dfiber.d" is my fiber example. I can run it on macppc
and powerpc64, and you should be able to run it on any dlang arch,

$ egdc -o dfiber dfiber.d
$ ./dfiber
adder(1, 1, 1)()
1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, 465, 753

But on macppc, egdc works only with ld.bfd,

$ ln -s /usr/bin/ld.bfd ld
$ PATH=$PWD:$PATH
$ egdc -o dfiber dfiber.d

Bump REVISION-dlang for libphobos. Don't bump REVISION, because
the other changes (patch-gcc_config_gcc, and %%powerpc64%% in
PLIST-main) affect only powerpc64, which was broken.

--George

Index: Makefile
===================================================================
RCS file: /cvs/ports/lang/gcc/11/Makefile,v
retrieving revision 1.3
diff -u -p -r1.3 Makefile
--- Makefile 24 Aug 2021 18:13:19 -0000 1.3
+++ Makefile 10 Oct 2021 23:40:00 -0000
@@ -12,7 +12,7 @@ ONLY_FOR_ARCHS = aarch64 alpha amd64 arm
powerpc powerpc64 sparc64

ONLY_FOR_ARCHS-ada = amd64 i386 mips64 powerpc
-ONLY_FOR_ARCHS-dlang = aarch64 amd64 arm i386 powerpc
+ONLY_FOR_ARCHS-dlang = aarch64 amd64 arm i386 powerpc powerpc64

DPB_PROPERTIES = parallel

@@ -20,6 +20,7 @@ V = 11.2.0
FULL_VERSION = $V
FULL_PKGVERSION = $V
REVISION = 0
+REVISION-dlang = 1

ADASTRAP-amd64 = adastrap-amd64-$V-0.tar.xz
ADASTRAP-arm = adastrap-arm-4.9.4-0.tar.xz
Index: patches/patch-gcc_config_gcc
===================================================================
RCS file: /cvs/ports/lang/gcc/11/patches/patch-gcc_config_gcc,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 patch-gcc_config_gcc
--- patches/patch-gcc_config_gcc 15 Aug 2021 18:42:10 -0000 1.1.1.1
+++ patches/patch-gcc_config_gcc 10 Oct 2021 23:40:00 -0000
@@ -123,7 +123,7 @@ Index: gcc/config.gcc
+ ;;
+powerpc64*-*-openbsd*)
+ tm_defines="${tm_defines} DEFAULT_FLAG_PIE=2"
-+ tm_file="${tm_file} dbxelf.h elfos.h openbsd.h openbsd-stdint.h openbsd-libpthread.h freebsd-spec.h rs6000/sysv4.h rs6000/default64.h rs6000/openbsd64.h"
++ tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h openbsd.h openbsd-stdint.h openbsd-libpthread.h freebsd-spec.h rs6000/sysv4.h rs6000/default64.h rs6000/openbsd64.h"
+ tmake_file="${tmake_file} rs6000/t-openbsd64"
+ extra_options="${extra_options} rs6000/sysv4.opt rs6000/linux64.opt openbsd.opt"
+ ;;
Index: patches/patch-libphobos_configure
===================================================================
RCS file: patches/patch-libphobos_configure
diff -N patches/patch-libphobos_configure
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-libphobos_configure 10 Oct 2021 23:40:00 -0000
@@ -0,0 +1,17 @@
+$OpenBSD$
+
+Add fiber asm for powerpc64, to avoid
+"configure: error: setcontext required but not found"
+
+Index: libphobos/configure
+--- libphobos/configure.orig
++++ libphobos/configure
+@@ -15196,7 +15196,7 @@ fi
+ aarch64* | \
+ arm* | \
+ i[34567]86|x86_64 | \
+- powerpc)
++ powerpc*)
+ druntime_fiber_asm_external=yes
+ ;;
+ esac
Index: patches/patch-libphobos_libdruntime_config_powerpc_switchcontext_S
===================================================================
RCS file: patches/patch-libphobos_libdruntime_config_powerpc_switchcontext_S
diff -N patches/patch-libphobos_libdruntime_config_powerpc_switchcontext_S
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-libphobos_libdruntime_config_powerpc_switchcontext_S 10 Oct 2021 23:40:00 -0000
@@ -0,0 +1,224 @@
+$OpenBSD$
+
+Add fibers for powerpc64 ELFv2, and fix fibers for 32-bit powerpc ELF.
+The old code was for some other platform (AIX?), not BSD nor Linux.
+This patch fixes OpenBSD but might break the other platform.
+
+This patch doesn't save altivec registers v20..v31, because gcc
+disables altivec by default.
+
+Index: libphobos/libdruntime/config/powerpc/switchcontext.S
+--- libphobos/libdruntime/config/powerpc/switchcontext.S.orig
++++ libphobos/libdruntime/config/powerpc/switchcontext.S
+@@ -24,7 +24,210 @@ see the files COPYING3 and COPYING.RUNTIME respectivel
+
+ #include "../common/threadasm.S"
+
+-#if !defined(__PPC64__) && !defined(__MACH__)
++#if defined(__ELF__)
++
++/**
++ * Performs a context switch.
++ *
++ * r3 - old context pointer
++ * r4 - new context pointer
++ *
++ */
++ .text
++ .globl CSYM(fiber_switchContext)
++ .type CSYM(fiber_switchContext), @function
++ .align 2
++CSYM(fiber_switchContext):
++ .cfi_startproc
++#ifdef __PPC64__
++ /* ELF64 - Save linkage area */
++ mflr 0
++ mfcr 5
++ std 0, 16(1)
++ stw 5, 8(1)
++
++ /* Make room for 18 GPRs, 18 FPRs */
++ addi 6, 1, -18 * 8
++ addi 1, 6, -18 * 8
++
++ /* Save GPRs */
++ std 31, (17 * 8)(6)
++ std 30, (16 * 8)(6)
++ std 29, (15 * 8)(6)
++ std 28, (14 * 8)(6)
++ std 27, (13 * 8)(6)
++ std 26, (12 * 8)(6)
++ std 25, (11 * 8)(6)
++ std 24, (10 * 8)(6)
++ std 23, (9 * 8)(6)
++ std 22, (8 * 8)(6)
++ std 21, (7 * 8)(6)
++ std 20, (6 * 8)(6)
++ std 19, (5 * 8)(6)
++ std 18, (4 * 8)(6)
++ std 17, (3 * 8)(6)
++ std 16, (2 * 8)(6)
++ std 15, (1 * 8)(6)
++ std 14, (0 * 8)(6)
++#else
++ /* ELF32 - Save linkage area */
++ mflr 0
++ mfcr 5
++ stw 0, 4(1)
++
++ /* Make room for 18 GPRs, CR, 18 FPRs; rounding up so r1 stays
++ 16-byte aligned. We must move r1, because ELF32 allows
++ signals to clobber below r1 (no red zone). */
++ addi 6, 1, -20 * 4
++ addi 1, 6, -18 * 8
++
++ /* Save GPRs */
++ stw 31, (19 * 4)(6)
++ stw 30, (18 * 4)(6)
++ stw 29, (17 * 4)(6)
++ stw 28, (16 * 4)(6)
++ stw 27, (15 * 4)(6)
++ stw 26, (14 * 4)(6)
++ stw 25, (13 * 4)(6)
++ stw 24, (12 * 4)(6)
++ stw 23, (11 * 4)(6)
++ stw 22, (10 * 4)(6)
++ stw 21, (9 * 4)(6)
++ stw 20, (8 * 4)(6)
++ stw 19, (7 * 4)(6)
++ stw 18, (6 * 4)(6)
++ stw 17, (5 * 4)(6)
++ stw 16, (4 * 4)(6)
++ stw 15, (3 * 4)(6)
++ stw 14, (2 * 4)(6)
++
++ /* Save condition register */
++ stw 5, 0(6)
++

No comments:

Post a Comment