Re: [PATCH v3 2/2] tools/nolibc: add support for 32-bit parisc

Helge Deller <[email protected]>
Newsgroups org.kernel.vger.linux-parisc,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On 4/9/26 10:38, Thomas Weißschuh wrote:
> 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?

No, it can happen if too many registers are in use and if you e.g. hand
over arg0 = a+x-z, arg1 = 100-z/3, .... (I mean if you put in multiple calculations).
For now I would ignore it.

> (...)
> 
>>> +#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.

I tried.
You are using "-display none" which is nearly the same.
The difference is: With "-display none", you will see the output starting when the kernel
switches to serial port".  With "-nographics" you will see everything from the start
of the virtual computer, e.g. BIOS messages, boot loader and initial kernel messages.

For your usecase either is OK.
  
>>>   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.

Yeah, but I think we can avoid libgcc other ways too.
I will try once it's upstreamed..

Helge
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.