Re: [PATCH 5/7] tools/nolibc: handle 64-bit system call arguments on MIPS N32
From: Thomas Weißschuh
Date: Sat Apr 18 2026 - 07:55:10 EST
Hey David,
Apr 18, 2026 13:14:46 David Laight <david.laight.linux@xxxxxxxxx>:
> 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.
I didn't think of this.
Personally I am fine with both variants.
The parameterized macro is a bit weird
is it breaks the normal syntax.
Let's wait what Willy thinks.
>> #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