[PATCH v2 4/5] LoongArch: Add support for LA32 in sysdeps/unix/sysv/linux/loongarch

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Thu Dec 18 13:05:38 GMT 2025



On 18/12/25 09:30, mengqinggang wrote:
> ---
>  sysdeps/unix/sysv/linux/loongarch/Makefile    |  4 +-
>  sysdeps/unix/sysv/linux/loongarch/clone.S     | 10 ++---
>  sysdeps/unix/sysv/linux/loongarch/clone3.S    |  8 ++--
>  sysdeps/unix/sysv/linux/loongarch/configure   | 40 +++++++++++++++++++
>  .../unix/sysv/linux/loongarch/configure.ac    |  8 ++++
>  .../unix/sysv/linux/loongarch/getcontext.S    | 12 +++---
>  .../unix/sysv/linux/loongarch/gettimeofday.c  |  9 +++--
>  .../unix/sysv/linux/loongarch/ldd-rewrite.sed |  2 +-
>  .../linux/loongarch/{ => lp64}/arch-syscall.h |  0
>  .../unix/sysv/linux/loongarch/pointer_guard.h | 18 ++-------
>  .../unix/sysv/linux/loongarch/readelflib.c    | 33 +++++++++++----
>  .../unix/sysv/linux/loongarch/setcontext.S    | 24 +++++------
>  .../unix/sysv/linux/loongarch/shlib-versions  |  6 ++-
>  .../unix/sysv/linux/loongarch/swapcontext.S   | 28 ++++++-------
>  .../sysv/linux/loongarch/syscall_cancel.S     |  2 +-
>  sysdeps/unix/sysv/linux/loongarch/sysdep.S    |  8 ++--
>  sysdeps/unix/sysv/linux/loongarch/sysdep.h    | 30 +++++++++++---
>  .../sysv/linux/loongarch/ucontext-macros.h    |  6 ++-
>  sysdeps/unix/sysv/linux/loongarch/vfork.S     |  6 +--
>  19 files changed, 170 insertions(+), 84 deletions(-)
>  rename sysdeps/unix/sysv/linux/loongarch/{ => lp64}/arch-syscall.h (100%)
> 
> diff --git a/sysdeps/unix/sysv/linux/loongarch/Makefile b/sysdeps/unix/sysv/linux/loongarch/Makefile
> index c84a1762ed..0d5f087862 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/Makefile
> +++ b/sysdeps/unix/sysv/linux/loongarch/Makefile
> @@ -2,11 +2,13 @@ ifeq ($(subdir),stdlib)
>  gen-as-const-headers += ucontext_i.sym
>  endif
>  
> -abi-variants := lp64s lp64d
> +abi-variants := ilp32s ilp32d lp64s lp64d
>  
>  ifeq (,$(filter $(default-abi),$(abi-variants)))
>  $(error Unknown ABI $(default-abi), must be one of $(abi-variants))
>  endif
>  
> +abi-ilp32s-condition	:= __WORDSIZE == 32 && defined __loongarch_soft_float
> +abi-ilp32d-condition	:= __WORDSIZE == 32 && defined __loongarch_double_float
>  abi-lp64s-condition	:= __WORDSIZE == 64 && defined __loongarch_soft_float
>  abi-lp64d-condition	:= __WORDSIZE == 64 && defined __loongarch_double_float
> diff --git a/sysdeps/unix/sysv/linux/loongarch/clone.S b/sysdeps/unix/sysv/linux/loongarch/clone.S
> index 2a68dd31ea..c5a82ba2cc 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/clone.S
> +++ b/sysdeps/unix/sysv/linux/loongarch/clone.S
> @@ -33,13 +33,13 @@
>  ENTRY (__clone)
>  
>  	/* Align stack to 16.  */
> -	BSTRINS		a1, zero, 3, 0
> +	REG_ALIGN_ASM (a1, 4)
>  
>  	/* Sanity check arguments.  */
> -	beqz		a0, L (invalid) /* No NULL function pointers.  */
> -	beqz		a1, L (invalid) /* No NULL stack pointers.  */
> +	beq		a0, zero, L (invalid) /* No NULL function pointers.  */
> +	beq		a1, zero, L (invalid) /* No NULL stack pointers.  */
>  
> -	ADDI 		a1, a1, -16 /* Reserve argument save space.  */
> +	ADDI 		a1, a1, -STACK_ALIGN /* Reserve argument save space.  */
>  	REG_S		a0, a1, 0   /* Save function pointer.  */
>  	REG_S		a3, a1, SZREG   /* Save argument pointer.  */
>  
> @@ -54,7 +54,7 @@ ENTRY (__clone)
>  	syscall		0
>  
>  	blt		a0, zero ,L (error)
> -	beqz		a0,L (thread_start)
> +	beq		a0, zero, L (thread_start)
>  
>  	/* Successful return from the parent.  */
>  	ret

Does it meant that loongarch32 does not support all the branch
instruction from loongarch64? Or that binutils is not recognizing 
beqz as a alias for beq reg, zero ?


> diff --git a/sysdeps/unix/sysv/linux/loongarch/clone3.S b/sysdeps/unix/sysv/linux/loongarch/clone3.S
> index 39d43ca6e8..d2c116e429 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/clone3.S
> +++ b/sysdeps/unix/sysv/linux/loongarch/clone3.S
> @@ -33,15 +33,15 @@
>  ENTRY (__clone3)
>  
>  	/* Sanity check arguments.  */
> -	beqz		a0, L (invalid)	/* No NULL cl_args pointer.  */
> -	beqz		a2, L (invalid)	/* No NULL function pointer.  */
> +	beq		a0, zero, L (invalid)	/* No NULL cl_args pointer.  */
> +	beq		a2, zero, L (invalid)	/* No NULL function pointer.  */
>  
>  	/* Do the system call.  */
>  	LI		a7, __NR_clone3
>  	syscall		0
>  
>  	blt		a0, zero ,L (error)
> -	beqz		a0, L (thread_start3)
> +	beq		a0, zero, L (thread_start3)
>  
>  	/* Successful return from the parent.  */
>  	ret
> @@ -67,7 +67,7 @@ L (thread_start3):
>  	cfi_undefined (1)
>  
>  	/* Align stack to 16.  */
> -	BSTRINS		sp, zero, 3, 0
> +	REG_ALIGN_ASM (sp, 4)
>  
>  	/* Set up arguments for the function call.  */
>  	move		a0, a3		/* Argument.  */
> diff --git a/sysdeps/unix/sysv/linux/loongarch/configure b/sysdeps/unix/sysv/linux/loongarch/configure
> index 914943f914..4a08e96487 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/configure
> +++ b/sysdeps/unix/sysv/linux/loongarch/configure
> @@ -152,6 +152,18 @@ then :
>  fi
>  rm -rf conftest*
>  
> +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h.  */
> +__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__
> +
> +_ACEOF
> +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
> +  $EGREP_TRADITIONAL "4 4 4" >/dev/null 2>&1
> +then :
> +  libc_cv_loongarch_int_abi=ilp32
> +fi
> +rm -rf conftest*
> +
>  if test $libc_cv_loongarch_int_abi = no; then
>    as_fn_error $? "Unable to determine integer ABI" "$LINENO" 5
>  fi
> @@ -193,6 +205,34 @@ config_vars="$config_vars
>  default-abi = $libc_cv_loongarch_int_abi$libc_cv_loongarch_float_abi"
>  
>  case $libc_cv_loongarch_int_abi$libc_cv_loongarch_float_abi in
> +ilp32s)
> +  test -n "$libc_cv_slibdir" ||
> +case "$prefix" in
> +/usr | /usr/)
> +  libc_cv_slibdir='/lib32/sf'
> +  libc_cv_rtlddir='/lib32'
> +  if test "$libdir" = '${exec_prefix}/lib'; then
> +    libdir='${exec_prefix}/lib32/sf';
> +    # Locale data can be shared between 32-bit and 64-bit libraries.
> +    libc_cv_complocaledir='${exec_prefix}/lib/locale'
> +  fi
> +  ;;
> +esac
> +  ;;
> +ilp32d)
> +  test -n "$libc_cv_slibdir" ||
> +case "$prefix" in
> +/usr | /usr/)
> +  libc_cv_slibdir='/lib32'
> +  libc_cv_rtlddir='/lib32'
> +  if test "$libdir" = '${exec_prefix}/lib'; then
> +    libdir='${exec_prefix}/lib32';
> +    # Locale data can be shared between 32-bit and 64-bit libraries.
> +    libc_cv_complocaledir='${exec_prefix}/lib/locale'
> +  fi
> +  ;;
> +esac
> +  ;;
>  lp64s)
>    test -n "$libc_cv_slibdir" ||
>  case "$prefix" in
> diff --git a/sysdeps/unix/sysv/linux/loongarch/configure.ac b/sysdeps/unix/sysv/linux/loongarch/configure.ac
> index 04e9150a9b..f020fd34ec 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/configure.ac
> +++ b/sysdeps/unix/sysv/linux/loongarch/configure.ac
> @@ -7,6 +7,8 @@ arch_minimum_kernel=5.19.0
>  libc_cv_loongarch_int_abi=no
>  AC_EGREP_CPP(4 8 8, [__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__
>    ], libc_cv_loongarch_int_abi=lp64)
> +AC_EGREP_CPP(4 4 4, [__SIZEOF_INT__ __SIZEOF_LONG__ __SIZEOF_POINTER__
> +  ], libc_cv_loongarch_int_abi=ilp32)
>  if test $libc_cv_loongarch_int_abi = no; then
>    AC_MSG_ERROR([Unable to determine integer ABI])
>  fi
> @@ -27,6 +29,12 @@ fi
>  LIBC_CONFIG_VAR([default-abi], [$libc_cv_loongarch_int_abi$libc_cv_loongarch_float_abi])
>  
>  case $libc_cv_loongarch_int_abi$libc_cv_loongarch_float_abi in
> +ilp32s)
> +  LIBC_SLIBDIR_RTLDDIR([lib32/sf], [lib32])
> +  ;;
> +ilp32d)
> +  LIBC_SLIBDIR_RTLDDIR([lib32], [lib32])
> +  ;;
>  lp64s)
>    LIBC_SLIBDIR_RTLDDIR([lib64/sf], [lib64])
>    ;;
> diff --git a/sysdeps/unix/sysv/linux/loongarch/getcontext.S b/sysdeps/unix/sysv/linux/loongarch/getcontext.S
> index 4e78c7c717..eef4c0c2cc 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/getcontext.S
> +++ b/sysdeps/unix/sysv/linux/loongarch/getcontext.S
> @@ -36,16 +36,16 @@ LEAF (__getcontext)
>  	SAVE_INT_REG (s6,  29, a0)
>  	SAVE_INT_REG (s7,  30, a0)
>  	SAVE_INT_REG (s8,  31, a0)
> -	st.d		ra, a0, MCONTEXT_PC
> +	REG_S		ra, a0, MCONTEXT_PC
>  
>  /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
> -	li.d		a3, _NSIG8
> -	li.d		a2, UCONTEXT_SIGMASK
> -	add.d		a2, a2, a0
> +	LI		a3, _NSIG8
> +	LI		a2, UCONTEXT_SIGMASK
> +	ADD		a2, a2, a0
>  	ori		a1, zero,0
> -	li.d		a0, SIG_BLOCK
> +	LI		a0, SIG_BLOCK
>  
> -	li.d		a7, SYS_ify (rt_sigprocmask)
> +	LI		a7, SYS_ify (rt_sigprocmask)
>  	syscall		0
>  	blt		a0, zero, 99f
>  
> diff --git a/sysdeps/unix/sysv/linux/loongarch/gettimeofday.c b/sysdeps/unix/sysv/linux/loongarch/gettimeofday.c
> index 93ea6ce445..b084d52769 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/gettimeofday.c
> +++ b/sysdeps/unix/sysv/linux/loongarch/gettimeofday.c
> @@ -17,6 +17,9 @@
>     License along with the GNU C Library.  If not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -
> -#define USE_IFUNC_GETTIMEOFDAY
> -#include <sysdeps/unix/sysv/linux/gettimeofday.c>
> +#ifdef __loongarch64
> +  #define USE_IFUNC_GETTIMEOFDAY
> +  #include <sysdeps/unix/sysv/linux/gettimeofday.c>
> +# else
> +  #include <sysdeps/unix/sysv/linux/gettimeofday.c>
> +#endif

Wouldn't be simpler to just:

  #ifdef __loongarch
  # define USE_IFUNC_GETTIMEOFDAY
  #endif
  #include <sysdeps/unix/sysv/linux/gettimeofday.c>

Does it meant that loongarch32 does not have ifunc support?

> diff --git a/sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed b/sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed
> index cdbe5c3dc5..a868370aca 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed
> +++ b/sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed
> @@ -1 +1 @@
> -s_^\(RTLDLIST=\)\(.*lib\)\(\|64\|32\)\(/ld-linux-loongarch-\)\(lp\|ilp\)\(64\|32\)\(d\|s\)\(\.so\.[0-9.]*\)[[:blank:]]*$_\1"\264\4lp64d\8 \264\4lp64s\8"_
> +s_^\(RTLDLIST=\)\(.*lib\)\(\|64\|32\)\(/ld-linux-loongarch-\)\(lp\|ilp\)\(64\|32\)\(d\|s\)\(\.so\.[0-9.]*\)[[:blank:]]*$_\1"\264\4lp64d\8 \264\4lp64s\8 \232\4ilp32d\8 \232\4ilp32s\8"_
> diff --git a/sysdeps/unix/sysv/linux/loongarch/arch-syscall.h b/sysdeps/unix/sysv/linux/loongarch/lp64/arch-syscall.h
> similarity index 100%
> rename from sysdeps/unix/sysv/linux/loongarch/arch-syscall.h
> rename to sysdeps/unix/sysv/linux/loongarch/lp64/arch-syscall.h
> diff --git a/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h b/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h
> index 00f4ad79ad..b08686d375 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h
> +++ b/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h
> @@ -19,26 +19,16 @@
>  #ifndef POINTER_GUARD_H
>  #define POINTER_GUARD_H
>  
> -/* Load a got-relative EXPR into register G.  */
> -#define LD_GLOBAL(G, EXPR) \
> -  la.global G,  EXPR; \
> -  REG_L     G,  G,  0;
> -
> -/* Load a pc-relative EXPR into register G.  */
> -#define LD_PCREL(G, EXPR) \
> -  pcalau12i G, %pc_hi20(EXPR); \
> -  REG_L     G, G, %pc_lo12(EXPR);
> -
>  #if (IS_IN (rtld) \
>       || (!defined SHARED && (IS_IN (libc) \
>       || IS_IN (libpthread))))
>  
>  #ifdef __ASSEMBLER__
>  #define PTR_MANGLE(dst, src, guard) \
> -  LD_PCREL (guard, __pointer_chk_guard_local); \
> +  LOAD_LOCAL (guard, __pointer_chk_guard_local); \
>    PTR_MANGLE2 (dst, src, guard);
>  #define PTR_DEMANGLE(dst, src, guard) \
> -  LD_PCREL (guard, __pointer_chk_guard_local); \
> +  LOAD_LOCAL (guard, __pointer_chk_guard_local); \
>    PTR_DEMANGLE2 (dst, src, guard);
>  /* Use PTR_MANGLE2 for efficiency if guard is already loaded.  */
>  #define PTR_MANGLE2(dst, src, guard) \
> @@ -57,10 +47,10 @@ extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
>  
>  #ifdef __ASSEMBLER__
>  #define PTR_MANGLE(dst, src, guard) \
> -  LD_GLOBAL (guard, __pointer_chk_guard); \
> +  LOAD_GLOBAL (guard, __pointer_chk_guard); \
>    PTR_MANGLE2 (dst, src, guard);
>  #define PTR_DEMANGLE(dst, src, guard) \
> -  LD_GLOBAL (guard, __pointer_chk_guard); \
> +  LOAD_GLOBAL (guard, __pointer_chk_guard); \
>    PTR_DEMANGLE2 (dst, src, guard);
>  /* Use PTR_MANGLE2 for efficiency if guard is already loaded.  */
>  #define PTR_MANGLE2(dst, src, guard) \
> diff --git a/sysdeps/unix/sysv/linux/loongarch/readelflib.c b/sysdeps/unix/sysv/linux/loongarch/readelflib.c
> index bb7d6d254b..9124f78f64 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/readelflib.c
> +++ b/sysdeps/unix/sysv/linux/loongarch/readelflib.c
> @@ -17,6 +17,9 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  
> +int process_elf32_file (const char *file_name, const char *lib,
> +			int *flag, unsigned int *isa_level, char **soname,
> +			void *file_contents, size_t file_length);
>  int process_elf64_file (const char *file_name, const char *lib,
>  			int *flag, unsigned int *isa_level, char **soname,
>  			void *file_contents, size_t file_length);
> @@ -31,6 +34,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
>  		  size_t file_length)
>  {
>    ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
> +  Elf32_Ehdr *elf32_header = (Elf32_Ehdr *) elf_header;
>    Elf64_Ehdr *elf64_header = (Elf64_Ehdr *) elf_header;
>    int ret;
>    long flags;
> @@ -38,15 +42,24 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
>    /* LoongArch libraries are always libc.so.6+.  */
>    *flag = FLAG_ELF_LIBC6;
>  
> -  ret = process_elf64_file (file_name, lib, flag, isa_level, soname,
> +  if (elf_header->e_ident[EI_CLASS] == ELFCLASS32)
> +    {
> +      ret = process_elf32_file (file_name, lib, flag, isa_level, soname,
> +				file_contents, file_length);
> +      flags = elf32_header->e_flags & ~EF_LARCH_OBJABI_V1;
> +    }
> +  else
> +    {
> +      ret = process_elf64_file (file_name, lib, flag, isa_level, soname,
>  				file_contents, file_length);
>  
> -  /* The EF_LARCH_OBJABI_V1 flag indicate which set of static relocations
> -   the object might use and it only considered during static linking,
> -   it does not reflect in runtime relocations.  However some binutils
> -   version might set it on dynamic shared object, so clear it to avoid
> -   see the SO as unsupported.  */
> -  flags = elf64_header->e_flags & ~EF_LARCH_OBJABI_V1;
> +      /* The EF_LARCH_OBJABI_V1 flag indicate which set of static relocations
> +       the object might use and it only considered during static linking,
> +       it does not reflect in runtime relocations.  However some binutils
> +       version might set it on dynamic shared object, so clear it to avoid
> +       see the SO as unsupported.  */
> +      flags = elf64_header->e_flags & ~EF_LARCH_OBJABI_V1;
> +    }
>  
>    /* LoongArch linkers encode the floating point ABI as part of the ELF headers.  */
>    switch (flags & SUPPORTED_ELF_FLAGS)
> @@ -70,6 +83,12 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
>  }
>  
>  #undef __ELF_NATIVE_CLASS
> +#undef process_elf_file
> +#define process_elf_file process_elf32_file
> +#define __ELF_NATIVE_CLASS 32
> +#include "elf/readelflib.c"
> +#undef __ELF_NATIVE_CLASS
> +
>  #undef process_elf_file
>  #define process_elf_file process_elf64_file
>  #define __ELF_NATIVE_CLASS 64
> diff --git a/sysdeps/unix/sysv/linux/loongarch/setcontext.S b/sysdeps/unix/sysv/linux/loongarch/setcontext.S
> index ef4830ad71..291c81b247 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/setcontext.S
> +++ b/sysdeps/unix/sysv/linux/loongarch/setcontext.S
> @@ -30,22 +30,22 @@
>  	.text
>  LEAF (__setcontext)
>  
> -	addi.d		sp, sp, -16
> -	st.d		a0, sp, 0	/* Save ucp to stack */
> +	ADDI		sp, sp, -16
> +	REG_S		a0, sp, 0	/* Save ucp to stack */
>  
>  /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */
> -	li.d		a3, _NSIG8
> -	li.d		a2, 0
> -	li.d		a1, UCONTEXT_SIGMASK
> -	add.d		a1, a1, a0
> -	li.d		a0, SIG_SETMASK
> +	LI		a3, _NSIG8
> +	LI		a2, 0
> +	LI		a1, UCONTEXT_SIGMASK
> +	ADD		a1, a1, a0
> +	LI		a0, SIG_SETMASK
>  
> -	li.d		a7, SYS_ify (rt_sigprocmask)
> +	LI		a7, SYS_ify (rt_sigprocmask)
>  	syscall		0
>  
>  	blt		a0, $r0, 99f
>  
> -	ld.d		t0, sp, 0	/* Load ucp to t0 */
> +	REG_L		t0, sp, 0	/* Load ucp to t0 */
>  	cfi_def_cfa (12, 0)
>  
>  /* Note the contents of argument registers will be random
> @@ -72,11 +72,11 @@ LEAF (__setcontext)
>  	RESTORE_INT_REG(s7,  30, t0)
>  	RESTORE_INT_REG(s8,  31, t0)
>  
> -	ld.d		t1, t0, MCONTEXT_PC
> +	REG_L		t1, t0, MCONTEXT_PC
>  	jirl		$r0,t1,0
>  
>  99:
> -	addi.d		sp, sp, 16
> +	ADDI		sp, sp, 16
>  	b		__syscall_error
>  
>  PSEUDO_END (__setcontext)
> @@ -92,7 +92,7 @@ LEAF (__start_context)
>  
>  	/* Invoke subsequent context if present, else exit(0).  */
>  	ori		a0, s2, 0
> -	beqz		s2, 1f
> +	beq		s2, zero, 1f
>  	bl		__setcontext
>  1:
>  	b		HIDDEN_JUMPTARGET(exit)
> diff --git a/sysdeps/unix/sysv/linux/loongarch/shlib-versions b/sysdeps/unix/sysv/linux/loongarch/shlib-versions
> index 5f40e7f5ec..8923e528c5 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/shlib-versions
> +++ b/sysdeps/unix/sysv/linux/loongarch/shlib-versions
> @@ -1,6 +1,10 @@
>  DEFAULT		GLIBC_2.36
>  
> -%if LOONGARCH_ABI_GRLEN == 64 && LOONGARCH_ABI_FRLEN == 64
> +%if LOONGARCH_ABI_GRLEN == 32 && LOONGARCH_ABI_FRLEN == 64
> +ld=ld-linux-loongarch-ilp32d.so.1
> +%elif LOONGARCH_ABI_GRLEN == 32 && LOONGARCH_ABI_FRLEN == 0
> +ld=ld-linux-loongarch-ilp32s.so.1
> +%elif LOONGARCH_ABI_GRLEN == 64 && LOONGARCH_ABI_FRLEN == 64
>  ld=ld-linux-loongarch-lp64d.so.1
>  %elif LOONGARCH_ABI_GRLEN == 64 && LOONGARCH_ABI_FRLEN == 0
>  ld=ld-linux-loongarch-lp64s.so.1
> diff --git a/sysdeps/unix/sysv/linux/loongarch/swapcontext.S b/sysdeps/unix/sysv/linux/loongarch/swapcontext.S
> index 4b8a90bc2e..0ebdf85738 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/swapcontext.S
> +++ b/sysdeps/unix/sysv/linux/loongarch/swapcontext.S
> @@ -22,8 +22,8 @@
>  
>  LEAF (__swapcontext)
>  	ori		a2, sp, 0		/* Save sp to a2 */
> -	addi.d		sp, sp, -16
> -	st.d		a1, sp, 0
> +	ADDI		sp, sp, -16
> +	REG_S		a1, sp, 0
>  	ori		t0, a1, 0
>  
>  	SAVE_INT_REG (ra,   1, a0)
> @@ -41,22 +41,22 @@ LEAF (__swapcontext)
>  	SAVE_INT_REG (s7,  30, a0)
>  	SAVE_INT_REG (s8,  31, a0)
>  
> -	st.d		ra, a0, MCONTEXT_PC
> +	REG_S		ra, a0, MCONTEXT_PC
>  
>  /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */
> -	li.d		a3, _NSIG8
> -	li.d		a2, UCONTEXT_SIGMASK
> -	add.d		a2, a2, a0
> -	li.d		a1, UCONTEXT_SIGMASK
> -	add.d		a1, a1, t0
> -	li.d		a0, SIG_SETMASK
> -
> -	li.d		a7, SYS_ify (rt_sigprocmask)
> +	LI		a3, _NSIG8
> +	LI		a2, UCONTEXT_SIGMASK
> +	ADD		a2, a2, a0
> +	LI		a1, UCONTEXT_SIGMASK
> +	ADD		a1, a1, t0
> +	LI		a0, SIG_SETMASK
> +
> +	LI		a7, SYS_ify (rt_sigprocmask)
>  	syscall		0
>  
>  	blt		a0, zero, 99f
>  
> -	ld.d		t0, sp, 0		/* Load a1 to t0 */
> +	REG_L		t0, sp, 0		/* Load a1 to t0 */
>  
>  /* Note the contents of argument registers will be random
>     unless makecontext() has been called.  */
> @@ -82,12 +82,12 @@ LEAF (__swapcontext)
>  	RESTORE_INT_REG (s7,  30, t0)
>  	RESTORE_INT_REG (s8,  31, t0)
>  
> -	ld.d		t1, t0, MCONTEXT_PC
> +	REG_L		t1, t0, MCONTEXT_PC
>  	jirl		$r0, t1, 0
>  
>  
>  99:
> -	addi.d		sp, sp, 16
> +	ADDI		sp, sp, 16
>  	b		__syscall_error
>  
>  PSEUDO_END (__swapcontext)
> diff --git a/sysdeps/unix/sysv/linux/loongarch/syscall_cancel.S b/sysdeps/unix/sysv/linux/loongarch/syscall_cancel.S
> index 1cc3d61626..a6c763d29d 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/syscall_cancel.S
> +++ b/sysdeps/unix/sysv/linux/loongarch/syscall_cancel.S
> @@ -28,7 +28,7 @@ __syscall_cancel_arch_start:
>  	     __syscall_do_cancel()  */
>  	ld.w	t0, a0, 0
>  	andi	t0, t0, TCB_CANCELED_BITMASK
> -	bnez	t0, 1f
> +	bne	t0, zero, 1f
>  
>  	/* Issue a 6 argument syscall.  */
>  	move	t1, a1
> diff --git a/sysdeps/unix/sysv/linux/loongarch/sysdep.S b/sysdeps/unix/sysv/linux/loongarch/sysdep.S
> index 1680022096..966195f79f 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/sysdep.S
> +++ b/sysdeps/unix/sysv/linux/loongarch/sysdep.S
> @@ -34,20 +34,20 @@ ENTRY (__syscall_set_errno)
>  /* We got here because a0 < 0, but only codes in the range [-4095, -1]
>     represent errors.  Otherwise, just return the result normally.
>   */
> -	li.d		t1, -4096
> +	LI		t1, -4096
>  	bgeu		t1, a0, L (out)
>  	sub.w		a0, zero, a0
>  #if RTLD_PRIVATE_ERRNO
>  	la		t1, rtld_errno
>  #elif defined(__PIC__)
>  	la.tls.ie	t1, errno
> -	add.d		t1, tp, t1
> +	ADD		t1, tp, t1
>  #else
>  	la.tls.le	t1, errno
> -	add.d		t1, tp, t1
> +	ADD		t1, tp, t1
>  #endif
>  	st.w		a0, t1, 0
> -	li.d		a0, -1
> +	LI		a0, -1
>  L (out):
>  	ret
>  END (__syscall_set_errno)
> diff --git a/sysdeps/unix/sysv/linux/loongarch/sysdep.h b/sysdeps/unix/sysv/linux/loongarch/sysdep.h
> index b9835d8391..461b89a610 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/sysdep.h
> +++ b/sysdeps/unix/sysv/linux/loongarch/sysdep.h
> @@ -34,9 +34,9 @@
>  #undef PSEUDO
>  #define PSEUDO(name, syscall_name, args) \
>    ENTRY (name); \
> -  li.d a7, SYS_ify (syscall_name); \
> +  LI a7, SYS_ify (syscall_name); \
>    syscall 0; \
> -  li.d a7, -4096; \
> +  LI a7, -4096; \
>    bltu a7, a0, .Lsyscall_error##name;
>  
>  #undef PSEUDO_END
> @@ -52,16 +52,16 @@
>    .Lsyscall_error##name : la t0, rtld_errno; \
>    sub.w a0, zero, a0; \
>    st.w a0, t0, 0; \
> -  li.d a0, -1;
> +  LI a0, -1;
>  
>  #else
>  
>  #define SYSCALL_ERROR_HANDLER(name) \
>    .Lsyscall_error##name : la.tls.ie t0, errno; \
> -  add.d t0, tp, t0; \
> +  ADD t0, tp, t0; \
>    sub.w a0, zero, a0; \
>    st.w a0, t0, 0; \
> -  li.d a0, -1;
> +  LI a0, -1;
>  
>  #endif
>  #else
> @@ -74,7 +74,7 @@
>  #undef PSEUDO_NEORRNO
>  #define PSEUDO_NOERRNO(name, syscall_name, args) \
>    ENTRY (name); \
> -  li.d a7, SYS_ify (syscall_name); \
> +  LI a7, SYS_ify (syscall_name); \
>    syscall 0;
>  
>  #undef PSEUDO_END_NOERRNO
> @@ -85,11 +85,17 @@
>  
>  /* Performs a system call, returning the error code.  */
>  #undef PSEUDO_ERRVAL
> +#if __loongarch_grlen == 64
>  #define PSEUDO_ERRVAL(name, syscall_name, args) \
>    PSEUDO_NOERRNO (name, syscall_name, args); \
>    slli.d a0, a0, 32; \
>    srai.d a0, a0, 32; /* sign_ext */ \
>    sub.d a0, zero, a0;
> +#else
> +#define PSEUDO_ERRVAL(name, syscall_name, args) \
> +  PSEUDO_NOERRNO (name, syscall_name, args); \
> +  sub.w a0, zero, a0;
> +#endif
>  
>  #undef PSEUDO_END_ERRVAL
>  #define PSEUDO_END_ERRVAL(name) END (name);
> @@ -109,6 +115,18 @@
>  #undef SYS_ify
>  #define SYS_ify(syscall_name) __NR_##syscall_name
>  
> +#if __WORDSIZE == 32
> +/* Workarounds for generic code needing to handle 64-bit time_t.  */
> +#define __NR_clock_getres	__NR_clock_getres_time64
> +#define __NR_futex		__NR_futex_time64
> +#define __NR_ppoll		__NR_ppoll_time64
> +#define __NR_pselect6		__NR_pselect6_time64
> +#define __NR_recvmmsg		__NR_recvmmsg_time64
> +#define __NR_rt_sigtimedwait	__NR_rt_sigtimedwait_time64
> +#define __NR_semtimedop		__NR_semtimedop_time64
> +#define __NR_utimensat		__NR_utimensat_time64
> +#endif /* __WORDSIZE == 32 */
> +
>  #ifndef __ASSEMBLER__
>  
>  #define VDSO_NAME "LINUX_5.10"
> diff --git a/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h b/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
> index 99bc8b0fa1..fd5da8d8ec 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
> +++ b/sysdeps/unix/sysv/linux/loongarch/ucontext-macros.h
> @@ -23,10 +23,12 @@
>  #include <sys/asm.h>
>  #include "ucontext_i.h"
>  
> +/* mcontext_t.__gregs is unsigned long long on la32 and la64,
> +   use 8 instead of SZREG.  */
>  #define SAVE_INT_REG(name, num, base) \
> -  REG_S name, base, ((num) *SZREG + MCONTEXT_GREGS)
> +  REG_S name, base, ((num) * 8 + MCONTEXT_GREGS)
>  
>  #define RESTORE_INT_REG(name, num, base) \
> -  REG_L name, base, ((num) *SZREG + MCONTEXT_GREGS)
> +  REG_L name, base, ((num) * 8 + MCONTEXT_GREGS)
>  
>  #endif /* _LINUX_LOONGARCH_UCONTEXT_MACROS_H */
> diff --git a/sysdeps/unix/sysv/linux/loongarch/vfork.S b/sysdeps/unix/sysv/linux/loongarch/vfork.S
> index 903d0f80ca..7001bdf8c5 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/vfork.S
> +++ b/sysdeps/unix/sysv/linux/loongarch/vfork.S
> @@ -28,11 +28,11 @@
>  
>  ENTRY (__vfork)
>  
> -	li.d	a0, 0x4111 /* CLONE_VM | CLONE_VFORK | SIGCHLD */
> -	add.d   a1, zero, sp
> +	LI	a0, 0x4111 /* CLONE_VM | CLONE_VFORK | SIGCHLD */
> +	ADD   a1, zero, sp
>  
>  	/* Do the system call.  */
> -	li.d	a7, __NR_clone
> +	LI	a7, __NR_clone
>  	syscall	0
>  
>  	blt	a0, zero ,L (error)



More information about the Libc-alpha mailing list