Re: [PATCH 5/7] tools/nolibc: handle 64-bit system call arguments on MIPS N32

From: David Laight

Date: Sat Apr 18 2026 - 07:18:55 EST


On Sat, 18 Apr 2026 12:20:00 +0200
Thomas Weißschuh <linux@xxxxxxxxxxxxxx> wrote:

> The N32 system call ABI expects 64-bit values directly in registers.
> This does not work on nolibc currently, as a 'long' is only 32 bits
> wide. Switch the system call wrappers to use 'long long' instead which
> can handle 64-bit values on N32. As on N64 'long' and 'long long' are
> the same, this does not change the behavior there.
>
> Signed-off-by: Thomas Weißschuh <linux@xxxxxxxxxxxxxx>
> ---
> tools/include/nolibc/arch-mips.h | 94 +++++++++++++++++++++-------------------
> 1 file changed, 49 insertions(+), 45 deletions(-)
>
> diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h
> index bb9d580ea1b1..557ef34d9df8 100644
> --- a/tools/include/nolibc/arch-mips.h
> +++ b/tools/include/nolibc/arch-mips.h
> @@ -55,6 +55,8 @@
> #define _NOLIBC_SYSCALL_STACK_RESERVE "addiu $sp, $sp, -32\n"
> #define _NOLIBC_SYSCALL_STACK_UNRESERVE "addiu $sp, $sp, 32\n"
>
> +#define _NOLIBC_SYSCALL_REG register long
> +
> #else /* _ABIN32 || _ABI64 */
>
> /* binutils, GCC and clang disagree about register aliases, use numbers instead. */
> @@ -66,12 +68,14 @@
> #define _NOLIBC_SYSCALL_STACK_RESERVE
> #define _NOLIBC_SYSCALL_STACK_UNRESERVE
>
> +#define _NOLIBC_SYSCALL_REG register long long
> +
> #endif /* _ABIO32 */

Since you need to use a #define, did you think about:
#define _NOLIBC_SYSCALL_REG(var, reg) register long long var __asm__ (reg)
to shorten the lines and the repetitive pattern.

>
> #define __nolibc_syscall0(num) \
> ({ \
> - register long _num __asm__ ("v0") = (num); \
> - register long _arg4 __asm__ ("a3"); \
> + _NOLIBC_SYSCALL_REG _num __asm__ ("v0") = (num); \
> + _NOLIBC_SYSCALL_REG _arg4 __asm__ ("a3"); \

__NOLIBC_SYSCALL_REG(_num, "v0") = (num);
__NOLIBC_SYSCALL_REG(_arg4, "a3");

...

David