Re: [PATCH v3 2/2] tools/nolibc: add support for 32-bit parisc
Thomas Weißschuh <[email protected]>
| Newsgroups | org.kernel.vger.linux-parisc,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 2026-04-09 00:15:54+0200, Helge Deller wrote: > * Thomas Weißschuh <[email protected]>: > > Extend nolibc to target the 32-bit parisc architecture. > > 64-bit is not yet supported. > > > > Signed-off-by: Thomas Weißschuh <[email protected]> > > --- > > 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 | 8 +- > > 5 files changed, 194 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..8580be5c9c58 > > --- /dev/null > > +++ b/tools/include/nolibc/arch-parisc.h > > @@ -0,0 +1,178 @@ > > +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ > > +/* > > + * parisc/hppa (32-bit) specific definitions for NOLIBC > > + * Copyright (C) 2026 Thomas Weißschuh <[email protected]> > > + */ > > + > > +#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 > better: > the instruction after that is in the delay slot and executed before the jump > to 0x100 actually happens. Ack. > > + * - 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. > > side-note: > this is actually really tricky. > I've seen cases, where the syscalls were not using the given registers, > because the callers were too complicated and the compiler could not guarantee > to actually use the given register. This is weird. We are using the same pattern for all other architectures, too and so far that worked fine. Was it a compiler bug? (...) > > +#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" > > you can change that to "b _start_c\" (without ",n") and move it > one line up before the "ldo -4..." instruction. It's a little bit faster". > The ldo is then in the delay slot. Ack. > > + ); > > + __nolibc_entrypoint_epilogue(); > > +} > > +#endif /* NOLIBC_NO_RUNTIME */ (...) > > 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=%)" > > You could change that to (untested): > QEMU_ARGS_parisc32 = -M B160L -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)" -nographic Will try. > > 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 > > would be good if we could go without this... > But for the beginning it's ok. Why? As nolibc is compiled again for each application, any users which don't want this don't get it. For nolibc-test it avoids a dependency on libgcc. Thomas