From: Helge Deller <deller@gmx.de>
To: "Thomas Weißschuh" <linux@weissschuh.net>,
"James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
"Willy Tarreau" <w@1wt.eu>,
"John David Anglin" <dave.anglin@bell.net>
Cc: linux-kernel@vger.kernel.org, linux-parisc@vger.kernel.org
Subject: Re: [PATCH 3/3] tools/nolibc: add support for 32-bit parisc
Date: Tue, 7 Apr 2026 19:33:05 +0200 [thread overview]
Message-ID: <0fad3d18-72fa-4d99-b9ac-477964fdd654@gmx.de> (raw)
In-Reply-To: <20260407-nolibc-hppa-v1-3-f70b4509c44a@weissschuh.net>
On 4/7/26 18:37, Thomas Weißschuh wrote:
> Extend nolibc to target the 32-bit parisc architecture.
> 64-bit is not yet supported.
Adding 64-bit would be very cool.
Dave Anglin is currently working on adding 64-bit userspace support
to gcc/glibc (dynamic loader), but that takes some time.
In the meantime a 64-bit nolibc would be cool for testing.
Helge
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> ---
> tools/include/nolibc/Makefile | 2 +-
> tools/include/nolibc/arch-parisc.h | 178 +++++++++++++++++++++++++
> tools/include/nolibc/arch.h | 2 +
> tools/testing/selftests/nolibc/Makefile.nolibc | 6 +
> tools/testing/selftests/nolibc/run-tests.sh | 4 +-
> 5 files changed, 190 insertions(+), 2 deletions(-)
>
> diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile
> index 7455097cff69..81187126bf93 100644
> --- a/tools/include/nolibc/Makefile
> +++ b/tools/include/nolibc/Makefile
> @@ -17,7 +17,7 @@ endif
> # it defaults to this nolibc directory.
> OUTPUT ?= $(CURDIR)/
>
> -architectures := arm arm64 loongarch m68k mips powerpc riscv s390 sh sparc x86
> +architectures := arm arm64 loongarch m68k mips parisc powerpc riscv s390 sh sparc x86
> arch_files := arch.h $(addsuffix .h, $(addprefix arch-, $(architectures)))
> all_files := \
> byteswap.h \
> diff --git a/tools/include/nolibc/arch-parisc.h b/tools/include/nolibc/arch-parisc.h
> new file mode 100644
> index 000000000000..5918f45132bb
> --- /dev/null
> +++ b/tools/include/nolibc/arch-parisc.h
> @@ -0,0 +1,178 @@
> +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
> +/*
> + * parisc/hppa (32 and 64) specific definitions for NOLIBC
> + * Copyright (C) 2026 Thomas Weißschuh <linux@weissschuh.net>
> + */
> +
> +#ifndef _NOLIBC_ARCH_PARISC_H
> +#define _NOLIBC_ARCH_PARISC_H
> +
> +#if defined(__LP64__)
> +#error 64-bit not supported
> +#endif
> +
> +#include "compiler.h"
> +#include "crt.h"
> +
> +/* Syscalls for parisc :
> + * - syscall number is passed in r20
> + * - arguments are in r26 to r21
> + * - the system call is performed by calling "ble 0x100(%sr2, %r0)",
> + * the instruction after that is executed first, use it to load the number
> + * - syscall return comes in r28
> + * - the arguments are cast to long and assigned into the target
> + * registers which are then simply passed as registers to the asm code,
> + * so that we don't have to experience issues with register constraints.
> + */
> +
> +#define _NOLIBC_SYSCALL_CLOBBERLIST \
> + "memory", "%r1", "%r2", "%r4", "%r20", "%r29", "%r31"
> +
> +#define __nolibc_syscall0(num) \
> +({ \
> + register long _ret __asm__ ("r28"); \
> + \
> + __asm__ volatile ( \
> + "ble 0x100(%%sr2, %%r0)\n\t" \
> + "ldi %1, %%r20\n\t" \
> + : "=r"(_ret) \
> + : "i"(num) \
> + : _NOLIBC_SYSCALL_CLOBBERLIST \
> + ); \
> + _ret; \
> +})
> +
> +#define __nolibc_syscall1(num, arg1) \
> +({ \
> + register long _ret __asm__ ("r28"); \
> + register long _arg1 __asm__ ("r26") = (long)(arg1); \
> + \
> + __asm__ volatile ( \
> + "ble 0x100(%%sr2, %%r0)\n\t" \
> + "ldi %2, %%r20\n\t" \
> + : "=r"(_ret), \
> + "+r"(_arg1) \
> + : "i"(num) \
> + : _NOLIBC_SYSCALL_CLOBBERLIST \
> + ); \
> + _ret; \
> +})
> +
> +#define __nolibc_syscall2(num, arg1, arg2) \
> +({ \
> + register long _ret __asm__ ("r28"); \
> + register long _arg1 __asm__ ("r26") = (long)(arg1); \
> + register long _arg2 __asm__ ("r25") = (long)(arg2); \
> + \
> + __asm__ volatile ( \
> + "ble 0x100(%%sr2, %%r0)\n\t" \
> + "ldi %3, %%r20\n\t" \
> + : "=r"(_ret), \
> + "+r"(_arg1), "+r"(_arg2) \
> + : "i"(num) \
> + : _NOLIBC_SYSCALL_CLOBBERLIST \
> + ); \
> + _ret; \
> +})
> +
> +#define __nolibc_syscall3(num, arg1, arg2, arg3) \
> +({ \
> + register long _ret __asm__ ("r28"); \
> + register long _arg1 __asm__ ("r26") = (long)(arg1); \
> + register long _arg2 __asm__ ("r25") = (long)(arg2); \
> + register long _arg3 __asm__ ("r24") = (long)(arg3); \
> + \
> + __asm__ volatile ( \
> + "ble 0x100(%%sr2, %%r0)\n\t" \
> + "ldi %4, %%r20\n\t" \
> + : "=r"(_ret), \
> + "+r"(_arg1), "+r"(_arg2), "+r"(_arg3) \
> + : "i"(num) \
> + : _NOLIBC_SYSCALL_CLOBBERLIST \
> + ); \
> + _ret; \
> +})
> +
> +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \
> +({ \
> + register long _ret __asm__ ("r28"); \
> + register long _arg1 __asm__ ("r26") = (long)(arg1); \
> + register long _arg2 __asm__ ("r25") = (long)(arg2); \
> + register long _arg3 __asm__ ("r24") = (long)(arg3); \
> + register long _arg4 __asm__ ("r23") = (long)(arg4); \
> + \
> + __asm__ volatile ( \
> + "ble 0x100(%%sr2, %%r0)\n\t" \
> + "ldi %5, %%r20\n\t" \
> + : "=r"(_ret), \
> + "+r"(_arg1), "+r"(_arg2), "+r"(_arg3), "+r"(_arg4) \
> + : "i"(num) \
> + : _NOLIBC_SYSCALL_CLOBBERLIST \
> + ); \
> + _ret; \
> +})
> +
> +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
> +({ \
> + register long _ret __asm__ ("r28"); \
> + register long _arg1 __asm__ ("r26") = (long)(arg1); \
> + register long _arg2 __asm__ ("r25") = (long)(arg2); \
> + register long _arg3 __asm__ ("r24") = (long)(arg3); \
> + register long _arg4 __asm__ ("r23") = (long)(arg4); \
> + register long _arg5 __asm__ ("r22") = (long)(arg5); \
> + \
> + __asm__ volatile ( \
> + "ble 0x100(%%sr2, %%r0)\n\t" \
> + "ldi %6, %%r20\n\t" \
> + : "=r"(_ret), \
> + "+r"(_arg1), "+r"(_arg2), "+r"(_arg3), "+r"(_arg4), \
> + "+r"(_arg5) \
> + : "i"(num) \
> + : _NOLIBC_SYSCALL_CLOBBERLIST \
> + ); \
> + _ret; \
> +})
> +
> +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
> +({ \
> + register long _ret __asm__ ("r28"); \
> + register long _arg1 __asm__ ("r26") = (long)(arg1); \
> + register long _arg2 __asm__ ("r25") = (long)(arg2); \
> + register long _arg3 __asm__ ("r24") = (long)(arg3); \
> + register long _arg4 __asm__ ("r23") = (long)(arg4); \
> + register long _arg5 __asm__ ("r22") = (long)(arg5); \
> + register long _arg6 __asm__ ("r21") = (long)(arg6); \
> + \
> + __asm__ volatile ( \
> + "ble 0x100(%%sr2, %%r0)\n\t" \
> + "ldi %7, %%r20\n\t" \
> + : "=r"(_ret), \
> + "+r"(_arg1), "+r"(_arg2), "+r"(_arg3), "+r"(_arg4), \
> + "+r"(_arg5), "+r"(_arg6) \
> + : "i"(num) \
> + : _NOLIBC_SYSCALL_CLOBBERLIST \
> + ); \
> + _ret; \
> +})
> +
> +#ifndef NOLIBC_NO_RUNTIME
> +/* startup code */
> +void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
> +{
> + __asm__ volatile (
> + ".import $global$\n" /* Set up the dp register */
> + "ldil L%$global$, %dp\n"
> + "ldo R%$global$(%r27), %dp\n"
> +
> + "ldo -4(%r24), %r26\n" /* The sp register is special on parisc.
> + * r24 points to argv. Subtract 4 to get &argc.
> + * Pass that as first argument to _start_c.
> + */
> +
> + "b,n _start_c\n"
> + );
> + __nolibc_entrypoint_epilogue();
> +}
> +#endif /* NOLIBC_NO_RUNTIME */
> +
> +#endif /* _NOLIBC_ARCH_PARISC_H */
> diff --git a/tools/include/nolibc/arch.h b/tools/include/nolibc/arch.h
> index a3adaf433f2c..6dc45a78e972 100644
> --- a/tools/include/nolibc/arch.h
> +++ b/tools/include/nolibc/arch.h
> @@ -28,6 +28,8 @@
> #include "arch-m68k.h"
> #elif defined(__sh__)
> #include "arch-sh.h"
> +#elif defined(__hppa__)
> +#include "arch-parisc.h"
> #else
> #error Unsupported Architecture
> #endif
> diff --git a/tools/testing/selftests/nolibc/Makefile.nolibc b/tools/testing/selftests/nolibc/Makefile.nolibc
> index f30bc68470cc..e9494f3cbc03 100644
> --- a/tools/testing/selftests/nolibc/Makefile.nolibc
> +++ b/tools/testing/selftests/nolibc/Makefile.nolibc
> @@ -64,6 +64,7 @@ ARCH_s390x = s390
> ARCH_sparc32 = sparc
> ARCH_sparc64 = sparc
> ARCH_sh4 = sh
> +ARCH_parisc32 = parisc
> ARCH := $(or $(ARCH_$(XARCH)),$(XARCH))
>
> # kernel image names by architecture
> @@ -92,6 +93,7 @@ IMAGE_sparc32 = arch/sparc/boot/image
> IMAGE_sparc64 = arch/sparc/boot/image
> IMAGE_m68k = vmlinux
> IMAGE_sh4 = arch/sh/boot/zImage
> +IMAGE_parisc32 = vmlinux
> IMAGE = $(objtree)/$(IMAGE_$(XARCH))
> IMAGE_NAME = $(notdir $(IMAGE))
>
> @@ -121,6 +123,7 @@ DEFCONFIG_sparc32 = sparc32_defconfig
> DEFCONFIG_sparc64 = sparc64_defconfig
> DEFCONFIG_m68k = virt_defconfig
> DEFCONFIG_sh4 = rts7751r2dplus_defconfig
> +DEFCONFIG_parisc32 = defconfig
> DEFCONFIG = $(DEFCONFIG_$(XARCH))
>
> EXTRACONFIG_x32 = -e CONFIG_X86_X32_ABI
> @@ -159,6 +162,7 @@ QEMU_ARCH_sparc32 = sparc
> QEMU_ARCH_sparc64 = sparc64
> QEMU_ARCH_m68k = m68k
> QEMU_ARCH_sh4 = sh4
> +QEMU_ARCH_parisc32 = hppa
> QEMU_ARCH = $(QEMU_ARCH_$(XARCH))
>
> QEMU_ARCH_USER_ppc64le = ppc64le
> @@ -199,6 +203,7 @@ QEMU_ARGS_sparc32 = -M SS-5 -m 256M -append "console=ttyS0,115200 panic=-1 $(
> QEMU_ARGS_sparc64 = -M sun4u -append "console=ttyS0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
> QEMU_ARGS_m68k = -M virt -append "console=ttyGF0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
> QEMU_ARGS_sh4 = -M r2d -serial file:/dev/stdout -append "console=ttySC1,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
> +QEMU_ARGS_parisc32 = -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
Does it make sense to use the qemu "-nographic" option for parisc (and some other architectures) ?
That way everything runs much faster on the text console, and (at least) for parisc you don't need the "console=ttyS0" entry.
> QEMU_ARGS = -m 1G $(QEMU_ARGS_$(XARCH)) $(QEMU_ARGS_BIOS) $(QEMU_ARGS_EXTRA)
>
> # OUTPUT is only set when run from the main makefile, otherwise
> @@ -215,6 +220,7 @@ CFLAGS_i386 = $(call cc-option,-m32)
> CFLAGS_x32 = -mx32
> CFLAGS_arm = -marm
> CFLAGS_armthumb = -mthumb -march=armv6t2
> +CFLAGS_parisc32 = -mfast-indirect-calls
> CFLAGS_ppc = -m32 -mbig-endian -mno-vsx $(call cc-option,-mmultiple)
> CFLAGS_ppc64 = -m64 -mbig-endian -mno-vsx $(call cc-option,-mmultiple)
> CFLAGS_ppc64le = -m64 -mlittle-endian -mno-vsx $(call cc-option,-mabi=elfv2)
> diff --git a/tools/testing/selftests/nolibc/run-tests.sh b/tools/testing/selftests/nolibc/run-tests.sh
> index 3917cfb8fdc4..981a680cebfb 100755
> --- a/tools/testing/selftests/nolibc/run-tests.sh
> +++ b/tools/testing/selftests/nolibc/run-tests.sh
> @@ -28,6 +28,7 @@ all_archs=(
> sparc32 sparc64
> m68k
> sh4
> + parisc32
> )
> archs="${all_archs[@]}"
>
> @@ -116,6 +117,7 @@ crosstool_arch() {
> s390*) echo s390;;
> sparc*) echo sparc64;;
> x32*) echo x86_64;;
> + parisc32) echo hppa;;
> *) echo "$1";;
> esac
> }
> @@ -185,7 +187,7 @@ test_arch() {
> exit 1
> esac
> printf '%-15s' "$arch:"
> - if [ "$arch" = "m68k" -o "$arch" = "sh4" ] && [ "$llvm" = "1" ]; then
> + if [ "$arch" = "m68k" -o "$arch" = "sh4" -o "$arch" = "parisc32" ] && [ "$llvm" = "1" ]; then
> echo "Unsupported configuration"
> return
> fi
>
next prev parent reply other threads:[~2026-04-07 17:33 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-07 16:37 [PATCH 0/3] " Thomas Weißschuh
2026-04-07 16:37 ` [PATCH 1/3] parisc: Makefile: use the regular compiler to build a native 32-bit vDSO Thomas Weißschuh
2026-04-07 17:14 ` Helge Deller
2026-04-07 18:06 ` Thomas Weißschuh
2026-04-07 19:27 ` Helge Deller
2026-04-07 20:20 ` Helge Deller
2026-04-07 21:27 ` Thomas Weißschuh
2026-04-07 22:33 ` Helge Deller
2026-04-07 16:37 ` [PATCH 2/3] selftests/nolibc: avoid function pointer comparisons Thomas Weißschuh
2026-04-07 17:20 ` Helge Deller
2026-04-07 18:11 ` Thomas Weißschuh
2026-04-07 16:37 ` [PATCH 3/3] tools/nolibc: add support for 32-bit parisc Thomas Weißschuh
2026-04-07 17:33 ` Helge Deller [this message]
2026-04-07 18:14 ` Thomas Weißschuh
2026-04-07 18:40 ` Helge Deller
2026-04-07 18:50 ` Thomas Weißschuh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0fad3d18-72fa-4d99-b9ac-477964fdd654@gmx.de \
--to=deller@gmx.de \
--cc=James.Bottomley@HansenPartnership.com \
--cc=dave.anglin@bell.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-parisc@vger.kernel.org \
--cc=linux@weissschuh.net \
--cc=w@1wt.eu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®