3327 lines
117 KiB
Diff
3327 lines
117 KiB
Diff
From 711d9fa407fd05c18dcf864a6f3a676a26e0b47d Mon Sep 17 00:00:00 2001
|
|
From: Peng Fan <fanpeng@loongson.cn>
|
|
Date: Mon, 3 Jul 2023 19:48:26 +0800
|
|
Subject: [PATCH] LoongArch: add new relocs and fix from upstream
|
|
|
|
Signed-off-by: Peng Fan <fanpeng@loongson.cn>
|
|
---
|
|
elf/cache.c | 6 +
|
|
elf/elf.h | 49 +++++
|
|
scripts/build-many-glibcs.py | 4 +
|
|
sysdeps/generic/ldconfig.h | 2 +
|
|
sysdeps/loongarch/Makefile | 14 +-
|
|
sysdeps/loongarch/__longjmp.S | 9 +
|
|
sysdeps/loongarch/bits/setjmp.h | 3 +
|
|
sysdeps/loongarch/configure | 98 +++++++++
|
|
sysdeps/loongarch/configure.ac | 58 ++++++
|
|
sysdeps/loongarch/dl-link.sym | 14 ++
|
|
sysdeps/loongarch/dl-machine.h | 42 ++--
|
|
sysdeps/loongarch/dl-trampoline.S | 186 +++++++++++++++++-
|
|
sysdeps/loongarch/fpu/e_ilogb.c | 39 ++++
|
|
sysdeps/loongarch/fpu/e_ilogbf.c | 39 ++++
|
|
sysdeps/loongarch/fpu/e_scalb.c | 60 ++++++
|
|
sysdeps/loongarch/fpu/e_scalbf.c | 60 ++++++
|
|
sysdeps/loongarch/fpu/get-rounding-mode.h | 38 ++++
|
|
sysdeps/loongarch/fpu/math-barriers.h | 28 +++
|
|
sysdeps/loongarch/fpu/math-use-builtins-fma.h | 4 +
|
|
.../loongarch/fpu/math-use-builtins-fmax.h | 10 +
|
|
.../loongarch/fpu/math-use-builtins-fmin.h | 10 +
|
|
.../loongarch/fpu/math-use-builtins-llrint.h | 10 +
|
|
.../loongarch/fpu/math-use-builtins-logb.h | 10 +
|
|
.../loongarch/fpu/math-use-builtins-lrint.h | 10 +
|
|
.../loongarch/fpu/math-use-builtins-rint.h | 9 +
|
|
sysdeps/loongarch/fpu/s_finite.c | 30 +++
|
|
sysdeps/loongarch/fpu/s_finitef.c | 30 +++
|
|
sysdeps/loongarch/fpu/s_fmaximum.c | 40 ++++
|
|
sysdeps/loongarch/fpu/s_fmaximum_mag.c | 40 ++++
|
|
sysdeps/loongarch/fpu/s_fmaximum_mag_num.c | 48 +++++
|
|
sysdeps/loongarch/fpu/s_fmaximum_mag_numf.c | 48 +++++
|
|
sysdeps/loongarch/fpu/s_fmaximum_magf.c | 40 ++++
|
|
sysdeps/loongarch/fpu/s_fmaximum_num.c | 48 +++++
|
|
sysdeps/loongarch/fpu/s_fmaximum_numf.c | 49 +++++
|
|
sysdeps/loongarch/fpu/s_fmaximumf.c | 40 ++++
|
|
sysdeps/loongarch/fpu/s_fmaxmag.c | 29 +++
|
|
sysdeps/loongarch/fpu/s_fmaxmagf.c | 29 +++
|
|
sysdeps/loongarch/fpu/s_fminimum.c | 40 ++++
|
|
sysdeps/loongarch/fpu/s_fminimum_mag.c | 40 ++++
|
|
sysdeps/loongarch/fpu/s_fminimum_mag_num.c | 48 +++++
|
|
sysdeps/loongarch/fpu/s_fminimum_mag_numf.c | 48 +++++
|
|
sysdeps/loongarch/fpu/s_fminimum_magf.c | 40 ++++
|
|
sysdeps/loongarch/fpu/s_fminimum_num.c | 48 +++++
|
|
sysdeps/loongarch/fpu/s_fminimum_numf.c | 48 +++++
|
|
sysdeps/loongarch/fpu/s_fminimumf.c | 40 ++++
|
|
sysdeps/loongarch/fpu/s_fminmag.c | 29 +++
|
|
sysdeps/loongarch/fpu/s_fminmagf.c | 29 +++
|
|
sysdeps/loongarch/fpu/s_fpclassify.c | 38 ++++
|
|
sysdeps/loongarch/fpu/s_fpclassifyf.c | 38 ++++
|
|
sysdeps/loongarch/fpu/s_isinf.c | 30 +++
|
|
sysdeps/loongarch/fpu/s_isinff.c | 30 +++
|
|
sysdeps/loongarch/fpu/s_isnan.c | 31 +++
|
|
sysdeps/loongarch/fpu/s_isnanf.c | 31 +++
|
|
sysdeps/loongarch/fpu/s_issignaling.c | 29 +++
|
|
sysdeps/loongarch/fpu/s_issignalingf.c | 29 +++
|
|
sysdeps/loongarch/fpu/s_scalbn.c | 29 +++
|
|
sysdeps/loongarch/fpu/s_scalbnf.c | 29 +++
|
|
sysdeps/loongarch/fpu_control.h | 30 +++
|
|
sysdeps/loongarch/lp64/libm-test-ulps | 1 +
|
|
sysdeps/loongarch/nofpu/Implies | 1 +
|
|
.../loongarch/nofpu/math-tests-exceptions.h | 28 +++
|
|
sysdeps/loongarch/nofpu/math-tests-rounding.h | 27 +++
|
|
sysdeps/loongarch/preconfigure | 1 -
|
|
sysdeps/loongarch/preconfigure.ac | 1 -
|
|
sysdeps/loongarch/setjmp.S | 9 +
|
|
sysdeps/loongarch/start.S | 21 +-
|
|
sysdeps/loongarch/sys/asm.h | 1 +
|
|
sysdeps/unix/sysv/linux/loongarch/Makefile | 9 +
|
|
.../unix/sysv/linux/loongarch/bits/shmlba.h | 24 +++
|
|
sysdeps/unix/sysv/linux/loongarch/configure | 51 ++++-
|
|
.../unix/sysv/linux/loongarch/configure.ac | 22 ++-
|
|
sysdeps/unix/sysv/linux/loongarch/dl-cache.h | 82 ++++++++
|
|
.../unix/sysv/linux/loongarch/gettimeofday.c | 22 +++
|
|
.../unix/sysv/linux/loongarch/ldd-rewrite.sed | 2 +-
|
|
.../unix/sysv/linux/loongarch/readelflib.c | 76 +++++++
|
|
.../unix/sysv/linux/loongarch/shlib-versions | 2 +
|
|
sysdeps/unix/sysv/linux/loongarch/sysdep.h | 63 +++++-
|
|
sysdeps/unix/sysv/linux/syscall.c | 2 +-
|
|
78 files changed, 2444 insertions(+), 38 deletions(-)
|
|
create mode 100644 sysdeps/loongarch/dl-link.sym
|
|
create mode 100644 sysdeps/loongarch/fpu/e_ilogb.c
|
|
create mode 100644 sysdeps/loongarch/fpu/e_ilogbf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/e_scalb.c
|
|
create mode 100644 sysdeps/loongarch/fpu/e_scalbf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/get-rounding-mode.h
|
|
create mode 100644 sysdeps/loongarch/fpu/math-barriers.h
|
|
create mode 100644 sysdeps/loongarch/fpu/math-use-builtins-fma.h
|
|
create mode 100644 sysdeps/loongarch/fpu/math-use-builtins-fmax.h
|
|
create mode 100644 sysdeps/loongarch/fpu/math-use-builtins-fmin.h
|
|
create mode 100644 sysdeps/loongarch/fpu/math-use-builtins-llrint.h
|
|
create mode 100644 sysdeps/loongarch/fpu/math-use-builtins-logb.h
|
|
create mode 100644 sysdeps/loongarch/fpu/math-use-builtins-lrint.h
|
|
create mode 100644 sysdeps/loongarch/fpu/math-use-builtins-rint.h
|
|
create mode 100644 sysdeps/loongarch/fpu/s_finite.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_finitef.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fmaximum.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fmaximum_mag.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fmaximum_mag_num.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fmaximum_mag_numf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fmaximum_magf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fmaximum_num.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fmaximum_numf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fmaximumf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fmaxmag.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fmaxmagf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fminimum.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fminimum_mag.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fminimum_mag_num.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fminimum_mag_numf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fminimum_magf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fminimum_num.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fminimum_numf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fminimumf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fminmag.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fminmagf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fpclassify.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_fpclassifyf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_isinf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_isinff.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_isnan.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_isnanf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_issignaling.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_issignalingf.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_scalbn.c
|
|
create mode 100644 sysdeps/loongarch/fpu/s_scalbnf.c
|
|
create mode 100644 sysdeps/loongarch/nofpu/Implies
|
|
create mode 100644 sysdeps/loongarch/nofpu/math-tests-exceptions.h
|
|
create mode 100644 sysdeps/loongarch/nofpu/math-tests-rounding.h
|
|
create mode 100644 sysdeps/unix/sysv/linux/loongarch/bits/shmlba.h
|
|
create mode 100644 sysdeps/unix/sysv/linux/loongarch/dl-cache.h
|
|
create mode 100644 sysdeps/unix/sysv/linux/loongarch/gettimeofday.c
|
|
create mode 100644 sysdeps/unix/sysv/linux/loongarch/readelflib.c
|
|
|
|
diff --git a/elf/cache.c b/elf/cache.c
|
|
index 3d7d3a67..6f25b5a9 100644
|
|
--- a/elf/cache.c
|
|
+++ b/elf/cache.c
|
|
@@ -229,6 +229,12 @@ print_entry (const char *lib, int flag, uint64_t hwcap,
|
|
case FLAG_RISCV_FLOAT_ABI_DOUBLE:
|
|
fputs (",double-float", stdout);
|
|
break;
|
|
+ case FLAG_LARCH_FLOAT_ABI_SOFT:
|
|
+ fputs (",soft-float", stdout);
|
|
+ break;
|
|
+ case FLAG_LARCH_FLOAT_ABI_DOUBLE:
|
|
+ fputs (",double-float", stdout);
|
|
+ break;
|
|
case 0:
|
|
break;
|
|
default:
|
|
diff --git a/elf/elf.h b/elf/elf.h
|
|
index 014393f3..ba54f754 100644
|
|
--- a/elf/elf.h
|
|
+++ b/elf/elf.h
|
|
@@ -829,6 +829,15 @@ typedef struct
|
|
#define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers. */
|
|
#define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode. */
|
|
#define NT_MIPS_MSA 0x802 /* MIPS SIMD registers. */
|
|
+#define NT_LOONGARCH_CPUCFG 0xa00 /* LoongArch CPU config registers. */
|
|
+#define NT_LOONGARCH_CSR 0xa01 /* LoongArch control and
|
|
+ status registers. */
|
|
+#define NT_LOONGARCH_LSX 0xa02 /* LoongArch Loongson SIMD
|
|
+ Extension registers. */
|
|
+#define NT_LOONGARCH_LASX 0xa03 /* LoongArch Loongson Advanced
|
|
+ SIMD Extension registers. */
|
|
+#define NT_LOONGARCH_LBT 0xa04 /* LoongArch Loongson Binary
|
|
+ Translation registers. */
|
|
|
|
/* Legal values for the note segment descriptor types for object files. */
|
|
|
|
@@ -4151,6 +4160,46 @@ enum
|
|
#define R_LARCH_GNU_VTINHERIT 57
|
|
#define R_LARCH_GNU_VTENTRY 58
|
|
|
|
+/* reserved 59-63 */
|
|
+
|
|
+#define R_LARCH_B16 64
|
|
+#define R_LARCH_B21 65
|
|
+#define R_LARCH_B26 66
|
|
+#define R_LARCH_ABS_HI20 67
|
|
+#define R_LARCH_ABS_LO12 68
|
|
+#define R_LARCH_ABS64_LO20 69
|
|
+#define R_LARCH_ABS64_HI12 70
|
|
+#define R_LARCH_PCALA_HI20 71
|
|
+#define R_LARCH_PCALA_LO12 72
|
|
+#define R_LARCH_PCALA64_LO20 73
|
|
+#define R_LARCH_PCALA64_HI12 74
|
|
+#define R_LARCH_GOT_PC_HI20 75
|
|
+#define R_LARCH_GOT_PC_LO12 76
|
|
+#define R_LARCH_GOT64_PC_LO20 77
|
|
+#define R_LARCH_GOT64_PC_HI12 78
|
|
+#define R_LARCH_GOT_HI20 79
|
|
+#define R_LARCH_GOT_LO12 80
|
|
+#define R_LARCH_GOT64_LO20 81
|
|
+#define R_LARCH_GOT64_HI12 82
|
|
+#define R_LARCH_TLS_LE_HI20 83
|
|
+#define R_LARCH_TLS_LE_LO12 84
|
|
+#define R_LARCH_TLS_LE64_LO20 85
|
|
+#define R_LARCH_TLS_LE64_HI12 86
|
|
+#define R_LARCH_TLS_IE_PC_HI20 87
|
|
+#define R_LARCH_TLS_IE_PC_LO12 88
|
|
+#define R_LARCH_TLS_IE64_PC_LO20 89
|
|
+#define R_LARCH_TLS_IE64_PC_HI12 90
|
|
+#define R_LARCH_TLS_IE_HI20 91
|
|
+#define R_LARCH_TLS_IE_LO12 92
|
|
+#define R_LARCH_TLS_IE64_LO20 93
|
|
+#define R_LARCH_TLS_IE64_HI12 94
|
|
+#define R_LARCH_TLS_LD_PC_HI20 95
|
|
+#define R_LARCH_TLS_LD_HI20 96
|
|
+#define R_LARCH_TLS_GD_PC_HI20 97
|
|
+#define R_LARCH_TLS_GD_HI20 98
|
|
+#define R_LARCH_32_PCREL 99
|
|
+#define R_LARCH_RELAX 100
|
|
+
|
|
|
|
/* ARCompact/ARCv2 specific relocs. */
|
|
#define R_ARC_NONE 0x0
|
|
diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py
|
|
index da9b9059..1a130136 100755
|
|
--- a/scripts/build-many-glibcs.py
|
|
+++ b/scripts/build-many-glibcs.py
|
|
@@ -222,6 +222,10 @@ class Context(object):
|
|
os_name='linux-gnu',
|
|
variant='lp64d',
|
|
gcc_cfg=['--with-abi=lp64d','--disable-multilib'])
|
|
+ self.add_config(arch='loongarch64',
|
|
+ os_name='linux-gnu',
|
|
+ variant='lp64s',
|
|
+ gcc_cfg=['--with-abi=lp64s','--disable-multilib'])
|
|
self.add_config(arch='m68k',
|
|
os_name='linux-gnu',
|
|
gcc_cfg=['--disable-multilib'])
|
|
diff --git a/sysdeps/generic/ldconfig.h b/sysdeps/generic/ldconfig.h
|
|
index 7cc898db..4281372b 100644
|
|
--- a/sysdeps/generic/ldconfig.h
|
|
+++ b/sysdeps/generic/ldconfig.h
|
|
@@ -45,6 +45,8 @@
|
|
#define FLAG_MIPS64_LIBN64_NAN2008 0x0e00
|
|
#define FLAG_RISCV_FLOAT_ABI_SOFT 0x0f00
|
|
#define FLAG_RISCV_FLOAT_ABI_DOUBLE 0x1000
|
|
+#define FLAG_LARCH_FLOAT_ABI_SOFT 0x1100
|
|
+#define FLAG_LARCH_FLOAT_ABI_DOUBLE 0x1200
|
|
|
|
/* Name of auxiliary cache. */
|
|
#define _PATH_LDCONFIG_AUX_CACHE "/var/cache/ldconfig/aux-cache"
|
|
diff --git a/sysdeps/loongarch/Makefile b/sysdeps/loongarch/Makefile
|
|
index 41c34496..43d2f583 100644
|
|
--- a/sysdeps/loongarch/Makefile
|
|
+++ b/sysdeps/loongarch/Makefile
|
|
@@ -2,14 +2,16 @@ ifeq ($(subdir),misc)
|
|
sysdep_headers += sys/asm.h
|
|
endif
|
|
|
|
+ifeq ($(subdir),elf)
|
|
+gen-as-const-headers += dl-link.sym
|
|
+endif
|
|
+
|
|
# LoongArch's assembler also needs to know about PIC as it changes the
|
|
# definition of some assembler macros.
|
|
ASFLAGS-.os += $(pic-ccflag)
|
|
|
|
-abi-variants := lp64
|
|
-
|
|
-ifeq (,$(filter $(default-abi),$(abi-variants)))
|
|
-$(error Unknown ABI $(default-abi), must be one of $(abi-variants))
|
|
+# All the objects in lib*_nonshared.a need to be compiled with medium code
|
|
+# model or large applications may fail to link.
|
|
+ifeq (yes,$(have-cmodel-medium))
|
|
+CFLAGS-.oS += -mcmodel=medium
|
|
endif
|
|
-
|
|
-abi-lp64-condition := defined __loongarch_lp64
|
|
diff --git a/sysdeps/loongarch/__longjmp.S b/sysdeps/loongarch/__longjmp.S
|
|
index 37e73844..d6a99fcb 100644
|
|
--- a/sysdeps/loongarch/__longjmp.S
|
|
+++ b/sysdeps/loongarch/__longjmp.S
|
|
@@ -20,8 +20,15 @@
|
|
#include <sys/asm.h>
|
|
|
|
ENTRY (__longjmp)
|
|
+#ifdef PTR_MANGLE
|
|
+ REG_L t0, a0, 0*SZREG
|
|
+ PTR_DEMANGLE (ra, t0, t1)
|
|
+ REG_L t0, a0, 1*SZREG
|
|
+ PTR_DEMANGLE2 (sp, t0, t1)
|
|
+#else
|
|
REG_L ra, a0, 0*SZREG
|
|
REG_L sp, a0, 1*SZREG
|
|
+#endif
|
|
REG_L x, a0, 2*SZREG
|
|
REG_L fp, a0, 3*SZREG
|
|
REG_L s0, a0, 4*SZREG
|
|
@@ -34,6 +41,7 @@ ENTRY (__longjmp)
|
|
REG_L s7, a0, 11*SZREG
|
|
REG_L s8, a0, 12*SZREG
|
|
|
|
+#ifndef __loongarch_soft_float
|
|
FREG_L $f24, a0, 13*SZREG + 0*SZFREG
|
|
FREG_L $f25, a0, 13*SZREG + 1*SZFREG
|
|
FREG_L $f26, a0, 13*SZREG + 2*SZFREG
|
|
@@ -42,6 +50,7 @@ ENTRY (__longjmp)
|
|
FREG_L $f29, a0, 13*SZREG + 5*SZFREG
|
|
FREG_L $f30, a0, 13*SZREG + 6*SZFREG
|
|
FREG_L $f31, a0, 13*SZREG + 7*SZFREG
|
|
+#endif
|
|
|
|
sltui a0,a1,1
|
|
ADD a0, a0, a1 # a0 = (a1 == 0) ? 1 : a1
|
|
diff --git a/sysdeps/loongarch/bits/setjmp.h b/sysdeps/loongarch/bits/setjmp.h
|
|
index 42f8fa76..8b323ad2 100644
|
|
--- a/sysdeps/loongarch/bits/setjmp.h
|
|
+++ b/sysdeps/loongarch/bits/setjmp.h
|
|
@@ -31,8 +31,11 @@ typedef struct __jmp_buf_internal_tag
|
|
long int __fp;
|
|
/* Callee-saved registers. */
|
|
long int __regs[9];
|
|
+
|
|
+#ifndef __loongarch_soft_float
|
|
/* Callee-saved floating point registers. */
|
|
double __fpregs[8];
|
|
+#endif
|
|
|
|
} __jmp_buf[1];
|
|
|
|
diff --git a/sysdeps/loongarch/configure b/sysdeps/loongarch/configure
|
|
index 43b54d49..b3c203ba 100644
|
|
--- a/sysdeps/loongarch/configure
|
|
+++ b/sysdeps/loongarch/configure
|
|
@@ -3,3 +3,101 @@
|
|
|
|
$as_echo "#define HIDDEN_VAR_NEEDS_DYNAMIC_RELOC 1" >>confdefs.h
|
|
|
|
+
|
|
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the toolchain is sufficient to build static PIE on LoongArch" >&5
|
|
+$as_echo_n "checking if the toolchain is sufficient to build static PIE on LoongArch... " >&6; }
|
|
+if ${libc_cv_static_pie_on_loongarch+:} false; then :
|
|
+ $as_echo_n "(cached) " >&6
|
|
+else
|
|
+
|
|
+ cat > conftest1.S << EOF
|
|
+.global _start
|
|
+.type _start, @function
|
|
+_start:
|
|
+ li.w \$a7, 93
|
|
+ /* This ensures the assembler supports explicit reloc. */
|
|
+ pcalau12i \$a0, %pc_hi20(x)
|
|
+ ld.w \$a0, \$a0, %pc_lo12(x)
|
|
+ syscall 0
|
|
+
|
|
+.data
|
|
+x:
|
|
+ .word 0
|
|
+ /* This should produce an R_LARCH_RELATIVE in the static PIE. */
|
|
+ .dword _start
|
|
+EOF
|
|
+ cat > conftest2.S << EOF
|
|
+.global f
|
|
+.type f, @function
|
|
+f:
|
|
+ /* The linker should be able to handle this and produce a PLT entry. */
|
|
+ la.pcrel \$t0, \$t0, external_func
|
|
+ jirl \$zero, \$t0, 0
|
|
+EOF
|
|
+
|
|
+ libc_cv_static_pie_on_loongarch=no
|
|
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static-pie -nostdlib -fPIE -o conftest1 conftest1.S'
|
|
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
|
+ (eval $ac_try) 2>&5
|
|
+ ac_status=$?
|
|
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
|
+ test $ac_status = 0; }; } \
|
|
+ && { ac_try='LC_ALL=C $READELF -Wr conftest1 | grep -q R_LARCH_RELATIVE'
|
|
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
|
+ (eval $ac_try) 2>&5
|
|
+ ac_status=$?
|
|
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
|
+ test $ac_status = 0; }; } \
|
|
+ && ! { ac_try='LC_ALL=C $READELF -Wl conftest1 | grep -q INTERP'
|
|
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
|
+ (eval $ac_try) 2>&5
|
|
+ ac_status=$?
|
|
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
|
+ test $ac_status = 0; }; } \
|
|
+ && { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -shared -fPIC -o conftest2.so conftest2.S'
|
|
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
|
+ (eval $ac_try) 2>&5
|
|
+ ac_status=$?
|
|
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
|
+ test $ac_status = 0; }; } \
|
|
+ && { ac_try='LC_ALL=C $READELF -Wr conftest2.so | grep -q 'R_LARCH_JUMP_SLOT.*external_func''
|
|
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
|
+ (eval $ac_try) 2>&5
|
|
+ ac_status=$?
|
|
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
|
+ test $ac_status = 0; }; }
|
|
+ then
|
|
+ libc_cv_static_pie_on_loongarch=yes
|
|
+ fi
|
|
+ rm -rf conftest*
|
|
+fi
|
|
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_static_pie_on_loongarch" >&5
|
|
+$as_echo "$libc_cv_static_pie_on_loongarch" >&6; }
|
|
+
|
|
+if test "$libc_cv_static_pie_on_loongarch" = yes; then
|
|
+ $as_echo "#define SUPPORT_STATIC_PIE 1" >>confdefs.h
|
|
+
|
|
+fi
|
|
+
|
|
+ # Check if gcc supports option -mcmodel=medium.
|
|
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports option -mcmodel=medium" >&5
|
|
+$as_echo_n "checking whether $CC supports option -mcmodel=medium... " >&6; }
|
|
+if ${libc_cv_loongarch_cmodel_medium+:} false; then :
|
|
+ $as_echo_n "(cached) " >&6
|
|
+else
|
|
+
|
|
+ if { ac_try='${CC-cc} -c $CFLAGS -mcmodel=medium /dev/null 1>&5'
|
|
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
|
+ (eval $ac_try) 2>&5
|
|
+ ac_status=$?
|
|
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
|
+ test $ac_status = 0; }; }; then
|
|
+ libc_cv_loongarch_cmodel_medium=yes
|
|
+ else
|
|
+ libc_cv_loongarch_cmodel_medium=no
|
|
+ fi
|
|
+fi
|
|
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_loongarch_cmodel_medium" >&5
|
|
+$as_echo "$libc_cv_loongarch_cmodel_medium" >&6; }
|
|
+config_vars="$config_vars
|
|
+have-cmodel-medium = $libc_cv_loongarch_cmodel_medium"
|
|
diff --git a/sysdeps/loongarch/configure.ac b/sysdeps/loongarch/configure.ac
|
|
index f744367b..eaee4a9f 100644
|
|
--- a/sysdeps/loongarch/configure.ac
|
|
+++ b/sysdeps/loongarch/configure.ac
|
|
@@ -4,3 +4,61 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
|
|
dnl It is always possible to access static and hidden symbols in an
|
|
dnl position independent way.
|
|
AC_DEFINE(HIDDEN_VAR_NEEDS_DYNAMIC_RELOC)
|
|
+
|
|
+dnl Test if the toolchain is new enough for static PIE.
|
|
+dnl We need a GAS supporting explicit reloc (older GAS produces stack-based
|
|
+dnl reloc and triggers an internal error in the linker). And, we need GCC to
|
|
+dnl pass the correct linker flags for static PIE. GCC >= 13 and GAS >= 2.40
|
|
+dnl satisify the requirement, but a distro may backport static PIE support into
|
|
+dnl earlier GCC or Binutils releases as well.
|
|
+AC_CACHE_CHECK([if the toolchain is sufficient to build static PIE on LoongArch],
|
|
+libc_cv_static_pie_on_loongarch, [
|
|
+ cat > conftest1.S << EOF
|
|
+.global _start
|
|
+.type _start, @function
|
|
+_start:
|
|
+ li.w \$a7, 93
|
|
+ /* This ensures the assembler supports explicit reloc. */
|
|
+ pcalau12i \$a0, %pc_hi20(x)
|
|
+ ld.w \$a0, \$a0, %pc_lo12(x)
|
|
+ syscall 0
|
|
+
|
|
+.data
|
|
+x:
|
|
+ .word 0
|
|
+ /* This should produce an R_LARCH_RELATIVE in the static PIE. */
|
|
+ .dword _start
|
|
+EOF
|
|
+ cat > conftest2.S << EOF
|
|
+.global f
|
|
+.type f, @function
|
|
+f:
|
|
+ /* The linker should be able to handle this and produce a PLT entry. */
|
|
+ la.pcrel \$t0, \$t0, external_func
|
|
+ jirl \$zero, \$t0, 0
|
|
+EOF
|
|
+
|
|
+ libc_cv_static_pie_on_loongarch=no
|
|
+ if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -static-pie -nostdlib -fPIE -o conftest1 conftest1.S]) \
|
|
+ && AC_TRY_COMMAND([LC_ALL=C $READELF -Wr conftest1 | grep -q R_LARCH_RELATIVE]) \
|
|
+ && ! AC_TRY_COMMAND([LC_ALL=C $READELF -Wl conftest1 | grep -q INTERP]) \
|
|
+ && AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -shared -fPIC -o conftest2.so conftest2.S]) \
|
|
+ && AC_TRY_COMMAND([LC_ALL=C $READELF -Wr conftest2.so | grep -q 'R_LARCH_JUMP_SLOT.*external_func'])
|
|
+ then
|
|
+ libc_cv_static_pie_on_loongarch=yes
|
|
+ fi
|
|
+ rm -rf conftest* ])
|
|
+
|
|
+if test "$libc_cv_static_pie_on_loongarch" = yes; then
|
|
+ AC_DEFINE(SUPPORT_STATIC_PIE)
|
|
+fi
|
|
+
|
|
+ # Check if gcc supports option -mcmodel=medium.
|
|
+AC_CACHE_CHECK(whether $CC supports option -mcmodel=medium,
|
|
+ libc_cv_loongarch_cmodel_medium, [
|
|
+ if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS -mcmodel=medium /dev/null 1>&AS_MESSAGE_LOG_FD); then
|
|
+ libc_cv_loongarch_cmodel_medium=yes
|
|
+ else
|
|
+ libc_cv_loongarch_cmodel_medium=no
|
|
+ fi])
|
|
+LIBC_CONFIG_VAR([have-cmodel-medium], [$libc_cv_loongarch_cmodel_medium])
|
|
diff --git a/sysdeps/loongarch/dl-link.sym b/sysdeps/loongarch/dl-link.sym
|
|
new file mode 100644
|
|
index 00000000..868ab7c6
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/dl-link.sym
|
|
@@ -0,0 +1,14 @@
|
|
+#include <stddef.h>
|
|
+#include <sysdep.h>
|
|
+#include <link.h>
|
|
+
|
|
+DL_SIZEOF_RG sizeof(struct La_loongarch_regs)
|
|
+DL_SIZEOF_RV sizeof(struct La_loongarch_retval)
|
|
+
|
|
+DL_OFFSET_RG_A0 offsetof(struct La_loongarch_regs, lr_reg)
|
|
+DL_OFFSET_RG_FA0 offsetof(struct La_loongarch_regs, lr_fpreg)
|
|
+DL_OFFSET_RG_RA offsetof(struct La_loongarch_regs, lr_ra)
|
|
+DL_OFFSET_RG_SP offsetof(struct La_loongarch_regs, lr_sp)
|
|
+
|
|
+DL_OFFSET_RV_A0 offsetof(struct La_loongarch_retval, lrv_a0)
|
|
+DL_OFFSET_RV_FA0 offsetof(struct La_loongarch_retval, lrv_a1)
|
|
diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h
|
|
index c69c72d0..516d2421 100644
|
|
--- a/sysdeps/loongarch/dl-machine.h
|
|
+++ b/sysdeps/loongarch/dl-machine.h
|
|
@@ -166,8 +166,7 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
|
|
{
|
|
|
|
case R_LARCH_JUMP_SLOT:
|
|
- case __WORDSIZE == 64 ? R_LARCH_64:
|
|
- R_LARCH_32:
|
|
+ case __WORDSIZE == 64 ? R_LARCH_64 : R_LARCH_32:
|
|
*addr_field = value;
|
|
break;
|
|
|
|
@@ -175,18 +174,15 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
|
|
break;
|
|
|
|
#ifndef RTLD_BOOTSTRAP
|
|
- case __WORDSIZE == 64 ? R_LARCH_TLS_DTPMOD64:
|
|
- R_LARCH_TLS_DTPMOD32:
|
|
+ case __WORDSIZE == 64 ? R_LARCH_TLS_DTPMOD64 : R_LARCH_TLS_DTPMOD32:
|
|
*addr_field = sym_map->l_tls_modid;
|
|
break;
|
|
|
|
- case __WORDSIZE == 64 ? R_LARCH_TLS_DTPREL64:
|
|
- R_LARCH_TLS_DTPREL32:
|
|
+ case __WORDSIZE == 64 ? R_LARCH_TLS_DTPREL64 : R_LARCH_TLS_DTPREL32:
|
|
*addr_field = TLS_DTPREL_VALUE (sym) + reloc->r_addend;
|
|
break;
|
|
|
|
- case __WORDSIZE == 64 ? R_LARCH_TLS_TPREL64:
|
|
- R_LARCH_TLS_TPREL32:
|
|
+ case __WORDSIZE == 64 ? R_LARCH_TLS_TPREL64 : R_LARCH_TLS_TPREL32:
|
|
CHECK_STATIC_TLS (map, sym_map);
|
|
*addr_field = TLS_TPREL_VALUE (sym_map, sym) + reloc->r_addend;
|
|
break;
|
|
@@ -274,10 +270,34 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
|
|
/* If using PLTs, fill in the first two entries of .got.plt. */
|
|
if (l->l_info[DT_JMPREL])
|
|
{
|
|
- extern void _dl_runtime_resolve (void)
|
|
- __attribute__ ((visibility ("hidden")));
|
|
+ extern void _dl_runtime_resolve (void) attribute_hidden;
|
|
+ extern void _dl_runtime_profile (void) attribute_hidden;
|
|
+
|
|
ElfW (Addr) *gotplt = (ElfW (Addr) *) D_PTR (l, l_info[DT_PLTGOT]);
|
|
- gotplt[0] = (ElfW (Addr)) & _dl_runtime_resolve;
|
|
+
|
|
+ /* The got[0] entry contains the address of a function which gets
|
|
+ called to get the address of a so far unresolved function and
|
|
+ jump to it. The profiling extension of the dynamic linker allows
|
|
+ to intercept the calls to collect information. In this case we
|
|
+ don't store the address in the GOT so that all future calls also
|
|
+ end in this function. */
|
|
+ if (profile != 0)
|
|
+ {
|
|
+ gotplt[0] = (ElfW(Addr)) &_dl_runtime_profile;
|
|
+
|
|
+ if (GLRO(dl_profile) != NULL
|
|
+ && _dl_name_match_p (GLRO(dl_profile), l))
|
|
+ /* Say that we really want profiling and the timers are
|
|
+ started. */
|
|
+ GL(dl_profile_map) = l;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ /* This function will get called to fix up the GOT entry
|
|
+ indicated by the offset on the stack, and then jump to
|
|
+ the resolved address. */
|
|
+ gotplt[0] = (ElfW (Addr)) & _dl_runtime_resolve;
|
|
+ }
|
|
gotplt[1] = (ElfW (Addr)) l;
|
|
}
|
|
#endif
|
|
diff --git a/sysdeps/loongarch/dl-trampoline.S b/sysdeps/loongarch/dl-trampoline.S
|
|
index ad8ab0fd..f9070e8e 100644
|
|
--- a/sysdeps/loongarch/dl-trampoline.S
|
|
+++ b/sysdeps/loongarch/dl-trampoline.S
|
|
@@ -19,16 +19,20 @@
|
|
#include <sysdep.h>
|
|
#include <sys/asm.h>
|
|
|
|
+#include "dl-link.h"
|
|
+
|
|
/* Assembler veneer called from the PLT header code for lazy loading.
|
|
The PLT header passes its own args in t0-t2. */
|
|
-
|
|
-# define FRAME_SIZE (-((-10 * SZREG - 8 * SZFREG) & ALMASK))
|
|
+#ifdef __loongarch_soft_float
|
|
+#define FRAME_SIZE (-((-10 * SZREG) & ALMASK))
|
|
+#else
|
|
+#define FRAME_SIZE (-((-10 * SZREG - 8 * SZFREG) & ALMASK))
|
|
+#endif
|
|
|
|
ENTRY (_dl_runtime_resolve)
|
|
|
|
/* Save arguments to stack. */
|
|
ADDI sp, sp, -FRAME_SIZE
|
|
-
|
|
REG_S ra, sp, 9*SZREG
|
|
REG_S a0, sp, 1*SZREG
|
|
REG_S a1, sp, 2*SZREG
|
|
@@ -39,6 +43,7 @@ ENTRY (_dl_runtime_resolve)
|
|
REG_S a6, sp, 7*SZREG
|
|
REG_S a7, sp, 8*SZREG
|
|
|
|
+#ifndef __loongarch_soft_float
|
|
FREG_S fa0, sp, 10*SZREG + 0*SZFREG
|
|
FREG_S fa1, sp, 10*SZREG + 1*SZFREG
|
|
FREG_S fa2, sp, 10*SZREG + 2*SZFREG
|
|
@@ -47,6 +52,7 @@ ENTRY (_dl_runtime_resolve)
|
|
FREG_S fa5, sp, 10*SZREG + 5*SZFREG
|
|
FREG_S fa6, sp, 10*SZREG + 6*SZFREG
|
|
FREG_S fa7, sp, 10*SZREG + 7*SZFREG
|
|
+#endif
|
|
|
|
/* Update .got.plt and obtain runtime address of callee */
|
|
SLLI a1, t1, 1
|
|
@@ -67,6 +73,7 @@ ENTRY (_dl_runtime_resolve)
|
|
REG_L a6, sp, 7*SZREG
|
|
REG_L a7, sp, 8*SZREG
|
|
|
|
+#ifndef __loongarch_soft_float
|
|
FREG_L fa0, sp, 10*SZREG + 0*SZFREG
|
|
FREG_L fa1, sp, 10*SZREG + 1*SZFREG
|
|
FREG_L fa2, sp, 10*SZREG + 2*SZFREG
|
|
@@ -75,9 +82,182 @@ ENTRY (_dl_runtime_resolve)
|
|
FREG_L fa5, sp, 10*SZREG + 5*SZFREG
|
|
FREG_L fa6, sp, 10*SZREG + 6*SZFREG
|
|
FREG_L fa7, sp, 10*SZREG + 7*SZFREG
|
|
+#endif
|
|
|
|
ADDI sp, sp, FRAME_SIZE
|
|
|
|
/* Invoke the callee. */
|
|
jirl zero, t1, 0
|
|
END (_dl_runtime_resolve)
|
|
+
|
|
+
|
|
+ENTRY (_dl_runtime_profile)
|
|
+ /* LoongArch we get called with:
|
|
+ t0 linkr_map pointer
|
|
+ t1 the scaled offset stored in t0, which can be used
|
|
+ to calculate the offset of the current symbol in .rela.plt
|
|
+ t2 %hi(%pcrel(.got.plt)) stored in t2, no use in this function
|
|
+ t3 dl resolver entry point, no use in this function
|
|
+
|
|
+ Stack frame layout:
|
|
+ [sp, #96] La_loongarch_regs
|
|
+ [sp, #48] La_loongarch_retval
|
|
+ [sp, #40] frame size return from pltenter
|
|
+ [sp, #32] dl_profile_call saved a1
|
|
+ [sp, #24] dl_profile_call saved a0
|
|
+ [sp, #16] T1
|
|
+ [sp, #0] ra, fp <- fp
|
|
+ */
|
|
+
|
|
+# define OFFSET_T1 16
|
|
+# define OFFSET_SAVED_CALL_A0 OFFSET_T1 + 8
|
|
+# define OFFSET_FS OFFSET_SAVED_CALL_A0 + 16
|
|
+# define OFFSET_RV OFFSET_FS + 8
|
|
+# define OFFSET_RG OFFSET_RV + DL_SIZEOF_RV
|
|
+
|
|
+# define SF_SIZE (-(-(OFFSET_RG + DL_SIZEOF_RG) & ALMASK))
|
|
+
|
|
+ /* Save arguments to stack. */
|
|
+ ADDI sp, sp, -SF_SIZE
|
|
+ REG_S ra, sp, 0
|
|
+ REG_S fp, sp, 8
|
|
+
|
|
+ or fp, sp, zero
|
|
+
|
|
+ REG_S a0, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 0*SZREG
|
|
+ REG_S a1, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 1*SZREG
|
|
+ REG_S a2, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 2*SZREG
|
|
+ REG_S a3, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 3*SZREG
|
|
+ REG_S a4, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 4*SZREG
|
|
+ REG_S a5, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 5*SZREG
|
|
+ REG_S a6, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 6*SZREG
|
|
+ REG_S a7, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 7*SZREG
|
|
+
|
|
+#ifndef __loongarch_soft_float
|
|
+ FREG_S fa0, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 0*SZFREG
|
|
+ FREG_S fa1, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 1*SZFREG
|
|
+ FREG_S fa2, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 2*SZFREG
|
|
+ FREG_S fa3, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 3*SZFREG
|
|
+ FREG_S fa4, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 4*SZFREG
|
|
+ FREG_S fa5, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 5*SZFREG
|
|
+ FREG_S fa6, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 6*SZFREG
|
|
+ FREG_S fa7, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 7*SZFREG
|
|
+#endif
|
|
+
|
|
+ /* Update .got.plt and obtain runtime address of callee. */
|
|
+ SLLI a1, t1, 1
|
|
+ or a0, t0, zero
|
|
+ ADD a1, a1, t1
|
|
+ or a2, ra, zero /* return addr */
|
|
+ ADDI a3, fp, OFFSET_RG /* La_loongarch_regs pointer */
|
|
+ ADDI a4, fp, OFFSET_FS /* frame size return from pltenter */
|
|
+
|
|
+ REG_S a0, fp, OFFSET_SAVED_CALL_A0
|
|
+ REG_S a1, fp, OFFSET_SAVED_CALL_A0 + SZREG
|
|
+
|
|
+ la t2, _dl_profile_fixup
|
|
+ jirl ra, t2, 0
|
|
+
|
|
+ REG_L t3, fp, OFFSET_FS
|
|
+ bge t3, zero, 1f
|
|
+
|
|
+ /* Save the return. */
|
|
+ or t4, v0, zero
|
|
+
|
|
+ /* Restore arguments from stack. */
|
|
+ REG_L a0, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 0*SZREG
|
|
+ REG_L a1, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 1*SZREG
|
|
+ REG_L a2, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 2*SZREG
|
|
+ REG_L a3, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 3*SZREG
|
|
+ REG_L a4, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 4*SZREG
|
|
+ REG_L a5, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 5*SZREG
|
|
+ REG_L a6, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 6*SZREG
|
|
+ REG_L a7, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 7*SZREG
|
|
+
|
|
+#ifndef __loongarch_soft_float
|
|
+ FREG_L fa0, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 0*SZFREG
|
|
+ FREG_L fa1, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 1*SZFREG
|
|
+ FREG_L fa2, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 2*SZFREG
|
|
+ FREG_L fa3, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 3*SZFREG
|
|
+ FREG_L fa4, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 4*SZFREG
|
|
+ FREG_L fa5, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 5*SZFREG
|
|
+ FREG_L fa6, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 6*SZFREG
|
|
+ FREG_L fa7, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 7*SZFREG
|
|
+#endif
|
|
+
|
|
+ REG_L ra, fp, 0
|
|
+ REG_L fp, fp, SZREG
|
|
+
|
|
+ ADDI sp, sp, SF_SIZE
|
|
+ jirl zero, t4, 0
|
|
+
|
|
+1:
|
|
+ /* The new frame size is in t3. */
|
|
+ SUB sp, fp, t3
|
|
+ BSTRINS sp, zero, 3, 0
|
|
+
|
|
+ REG_S a0, fp, OFFSET_T1
|
|
+
|
|
+ or a0, sp, zero
|
|
+ ADDI a1, fp, SF_SIZE
|
|
+ or a2, t3, zero
|
|
+ la t5, memcpy
|
|
+ jirl ra, t5, 0
|
|
+
|
|
+ REG_L t6, fp, OFFSET_T1
|
|
+
|
|
+ /* Call the function. */
|
|
+ REG_L a0, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 0*SZREG
|
|
+ REG_L a1, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 1*SZREG
|
|
+ REG_L a2, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 2*SZREG
|
|
+ REG_L a3, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 3*SZREG
|
|
+ REG_L a4, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 4*SZREG
|
|
+ REG_L a5, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 5*SZREG
|
|
+ REG_L a6, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 6*SZREG
|
|
+ REG_L a7, fp, OFFSET_RG + DL_OFFSET_RG_A0 + 7*SZREG
|
|
+
|
|
+#ifndef __loongarch_soft_float
|
|
+ FREG_L fa0, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 0*SZFREG
|
|
+ FREG_L fa1, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 1*SZFREG
|
|
+ FREG_L fa2, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 2*SZFREG
|
|
+ FREG_L fa3, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 3*SZFREG
|
|
+ FREG_L fa4, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 4*SZFREG
|
|
+ FREG_L fa5, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 5*SZFREG
|
|
+ FREG_L fa6, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 6*SZFREG
|
|
+ FREG_L fa7, fp, OFFSET_RG + DL_OFFSET_RG_FA0 + 7*SZFREG
|
|
+#endif
|
|
+ jirl ra, t6, 0
|
|
+
|
|
+ REG_S a0, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_A0
|
|
+ REG_S a1, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_A0 + SZREG
|
|
+
|
|
+#ifndef __loongarch_soft_float
|
|
+ FREG_S fa0, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_FA0
|
|
+ FREG_S fa1, fp, OFFSET_SAVED_CALL_A0 + DL_OFFSET_RV_FA0 + SZFREG
|
|
+#endif
|
|
+
|
|
+ /* Setup call to pltexit. */
|
|
+ REG_L a0, fp, OFFSET_SAVED_CALL_A0
|
|
+ REG_L a1, fp, OFFSET_SAVED_CALL_A0 + SZREG
|
|
+ ADDI a2, fp, OFFSET_RG
|
|
+ ADDI a3, fp, OFFSET_RV
|
|
+ la t7, _dl_audit_pltexit
|
|
+ jirl ra, t7, 0
|
|
+
|
|
+ REG_L a0, fp, OFFSET_RV + DL_OFFSET_RV_A0
|
|
+ REG_L a1, fp, OFFSET_RV + DL_OFFSET_RV_A0 + SZREG
|
|
+
|
|
+#ifndef __loongarch_soft_float
|
|
+ FREG_L fa0, fp, OFFSET_RV + DL_OFFSET_RV_FA0
|
|
+ FREG_L fa1, fp, OFFSET_RV + DL_OFFSET_RV_FA0 + SZFREG
|
|
+#endif
|
|
+
|
|
+ /* RA from within La_loongarch_reg. */
|
|
+ REG_L ra, fp, OFFSET_RG + DL_OFFSET_RG_RA
|
|
+ or sp, fp, zero
|
|
+ ADDI sp, sp, SF_SIZE
|
|
+ REG_S fp, fp, SZREG
|
|
+
|
|
+ jirl zero, ra, 0
|
|
+
|
|
+END (_dl_runtime_profile)
|
|
diff --git a/sysdeps/loongarch/fpu/e_ilogb.c b/sysdeps/loongarch/fpu/e_ilogb.c
|
|
new file mode 100644
|
|
index 00000000..f9ada692
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/e_ilogb.c
|
|
@@ -0,0 +1,39 @@
|
|
+/* __ieee754_ilogb(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+int
|
|
+__ieee754_ilogb (double x)
|
|
+{
|
|
+ int x_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+
|
|
+ if (__glibc_unlikely (x_cond & _FCLASS_ZERO))
|
|
+ return FP_ILOGB0;
|
|
+ else if (__glibc_unlikely (x_cond & ( _FCLASS_NAN | _FCLASS_INF)))
|
|
+ return FP_ILOGBNAN;
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fabs.d \t%0, %1" : "=f" (x) : "f" (x));
|
|
+ asm volatile ("flogb.d \t%0, %1" : "=f" (x) : "f" (x));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
diff --git a/sysdeps/loongarch/fpu/e_ilogbf.c b/sysdeps/loongarch/fpu/e_ilogbf.c
|
|
new file mode 100644
|
|
index 00000000..e1da48ec
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/e_ilogbf.c
|
|
@@ -0,0 +1,39 @@
|
|
+/* __ieee754_ilogbf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+int
|
|
+__ieee754_ilogbf (float x)
|
|
+{
|
|
+ int x_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+
|
|
+ if (__glibc_unlikely (x_cond & _FCLASS_ZERO))
|
|
+ return FP_ILOGB0;
|
|
+ else if (__glibc_unlikely (x_cond & ( _FCLASS_NAN | _FCLASS_INF)))
|
|
+ return FP_ILOGBNAN;
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fabs.s \t%0, %1" : "=f" (x) : "f" (x));
|
|
+ asm volatile ("flogb.s \t%0, %1" : "=f" (x) : "f" (x));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
diff --git a/sysdeps/loongarch/fpu/e_scalb.c b/sysdeps/loongarch/fpu/e_scalb.c
|
|
new file mode 100644
|
|
index 00000000..9fdf21fa
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/e_scalb.c
|
|
@@ -0,0 +1,60 @@
|
|
+/* scalb(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-finite.h>
|
|
+#include <fpu_control.h>
|
|
+#include <float.h>
|
|
+
|
|
+double
|
|
+__ieee754_scalb (double x, double fn)
|
|
+{
|
|
+ int x_cond;
|
|
+ int fn_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (fn_cond) : "f" (fn));
|
|
+
|
|
+ if (__glibc_unlikely(( x_cond | fn_cond) & _FCLASS_NAN))
|
|
+ return x * fn;
|
|
+ else if (__glibc_unlikely(fn_cond & _FCLASS_INF))
|
|
+ {
|
|
+ if (!(fn_cond & _FCLASS_MINF))
|
|
+ return x * fn;
|
|
+ else
|
|
+ return x / -fn;
|
|
+ }
|
|
+ else if (__glibc_likely(-DBL_MAX < fn && fn < DBL_MAX))
|
|
+ {
|
|
+ double rint_fn, tmp;
|
|
+
|
|
+ /* rint_fn = rint(fn) */
|
|
+ asm volatile ("frint.d \t%0, %1" : "=f" (rint_fn) : "f" (fn));
|
|
+
|
|
+ if (rint_fn != fn )
|
|
+ return (x - x) / (x - x);
|
|
+
|
|
+ asm volatile ("ftintrz.l.d \t%0, %1" : "=f" (tmp) : "f" (rint_fn));
|
|
+ asm volatile ("fscaleb.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (tmp));
|
|
+ }
|
|
+ else
|
|
+ asm volatile ("fscaleb.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (fn));
|
|
+
|
|
+ return x;
|
|
+}
|
|
+libm_alias_finite (__ieee754_scalb, __scalb)
|
|
diff --git a/sysdeps/loongarch/fpu/e_scalbf.c b/sysdeps/loongarch/fpu/e_scalbf.c
|
|
new file mode 100644
|
|
index 00000000..fae2e92e
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/e_scalbf.c
|
|
@@ -0,0 +1,60 @@
|
|
+/* scalbf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-finite.h>
|
|
+#include <fpu_control.h>
|
|
+#include <float.h>
|
|
+
|
|
+float
|
|
+__ieee754_scalbf (float x, float fn)
|
|
+{
|
|
+ int x_cond;
|
|
+ int fn_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (fn_cond) : "f" (fn));
|
|
+
|
|
+ if (__glibc_unlikely(( x_cond | fn_cond) & _FCLASS_NAN))
|
|
+ return x * fn;
|
|
+ else if (__glibc_unlikely(fn_cond & _FCLASS_INF))
|
|
+ {
|
|
+ if (!(fn_cond & _FCLASS_MINF))
|
|
+ return x * fn;
|
|
+ else
|
|
+ return x / -fn;
|
|
+ }
|
|
+ else if (__glibc_likely(-FLT_MAX < fn && fn < FLT_MAX))
|
|
+ {
|
|
+ float rintf_fn, tmp;
|
|
+
|
|
+ /* rintf_fn = rintf(fn) */
|
|
+ asm volatile ("frint.s \t%0, %1" : "=f" (rintf_fn) : "f" (fn));
|
|
+
|
|
+ if (rintf_fn != fn )
|
|
+ return (x - x) / (x - x);
|
|
+
|
|
+ asm volatile ("ftintrz.w.s \t%0, %1" : "=f" (tmp) : "f" (rintf_fn));
|
|
+ asm volatile ("fscaleb.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (tmp));
|
|
+ }
|
|
+ else
|
|
+ asm volatile ("fscaleb.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (fn));
|
|
+
|
|
+ return x;
|
|
+}
|
|
+libm_alias_finite (__ieee754_scalb, __scalb)
|
|
diff --git a/sysdeps/loongarch/fpu/get-rounding-mode.h b/sysdeps/loongarch/fpu/get-rounding-mode.h
|
|
new file mode 100644
|
|
index 00000000..b60733e2
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/get-rounding-mode.h
|
|
@@ -0,0 +1,38 @@
|
|
+/* Determine floating-point rounding mode within libc. LoongArch version.
|
|
+
|
|
+ Copyright (C) 2022-2023 Free Software Foundation, Inc.
|
|
+
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#ifndef _LARCH_GET_ROUNDING_MODE_H
|
|
+#define _LARCH_GET_ROUNDING_MODE_H 1
|
|
+
|
|
+#include <fenv.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+/* Return the floating-point rounding mode. */
|
|
+
|
|
+static inline int
|
|
+get_rounding_mode (void)
|
|
+{
|
|
+ fpu_control_t fpcr;
|
|
+
|
|
+ _FPU_GETCW (fpcr);
|
|
+ return fpcr & _FPU_RC_MASK;
|
|
+}
|
|
+
|
|
+#endif /* get-rounding-mode.h */
|
|
diff --git a/sysdeps/loongarch/fpu/math-barriers.h b/sysdeps/loongarch/fpu/math-barriers.h
|
|
new file mode 100644
|
|
index 00000000..3e977e43
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/math-barriers.h
|
|
@@ -0,0 +1,28 @@
|
|
+/* Control when floating-point expressions are evaluated. LoongArch version.
|
|
+ Copyright (C) 2023 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#ifndef _LOONGARCH_MATH_BARRIERS_H
|
|
+#define _LOONGARCH_MATH_BARRIERS_H 1
|
|
+
|
|
+/* Generic code forces values to memory; we don't need to do that. */
|
|
+#define math_opt_barrier(x) \
|
|
+ ({ __typeof (x) __x = (x); __asm ("" : "+frm" (__x)); __x; })
|
|
+#define math_force_eval(x) \
|
|
+ ({ __typeof (x) __x = (x); __asm __volatile__ ("" : : "frm" (__x)); })
|
|
+
|
|
+#endif /* math-barriers.h */
|
|
diff --git a/sysdeps/loongarch/fpu/math-use-builtins-fma.h b/sysdeps/loongarch/fpu/math-use-builtins-fma.h
|
|
new file mode 100644
|
|
index 00000000..eede75aa
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/math-use-builtins-fma.h
|
|
@@ -0,0 +1,4 @@
|
|
+#define USE_FMA_BUILTIN 1
|
|
+#define USE_FMAF_BUILTIN 1
|
|
+#define USE_FMAL_BUILTIN 0
|
|
+#define USE_FMAF128_BUILTIN 0
|
|
diff --git a/sysdeps/loongarch/fpu/math-use-builtins-fmax.h b/sysdeps/loongarch/fpu/math-use-builtins-fmax.h
|
|
new file mode 100644
|
|
index 00000000..5d22567b
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/math-use-builtins-fmax.h
|
|
@@ -0,0 +1,10 @@
|
|
+#if __GNUC_PREREQ (13, 0)
|
|
+# define USE_FMAX_BUILTIN 1
|
|
+# define USE_FMAXF_BUILTIN 1
|
|
+#else
|
|
+# define USE_FMAX_BUILTIN 0
|
|
+# define USE_FMAXF_BUILTIN 0
|
|
+#endif
|
|
+
|
|
+#define USE_FMAXL_BUILTIN 0
|
|
+#define USE_FMAXF128_BUILTIN 0
|
|
diff --git a/sysdeps/loongarch/fpu/math-use-builtins-fmin.h b/sysdeps/loongarch/fpu/math-use-builtins-fmin.h
|
|
new file mode 100644
|
|
index 00000000..4d28b41c
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/math-use-builtins-fmin.h
|
|
@@ -0,0 +1,10 @@
|
|
+#if __GNUC_PREREQ (13, 0)
|
|
+# define USE_FMIN_BUILTIN 1
|
|
+# define USE_FMINF_BUILTIN 1
|
|
+#else
|
|
+# define USE_FMIN_BUILTIN 0
|
|
+# define USE_FMINF_BUILTIN 0
|
|
+#endif
|
|
+
|
|
+#define USE_FMINL_BUILTIN 0
|
|
+#define USE_FMINF128_BUILTIN 0
|
|
diff --git a/sysdeps/loongarch/fpu/math-use-builtins-llrint.h b/sysdeps/loongarch/fpu/math-use-builtins-llrint.h
|
|
new file mode 100644
|
|
index 00000000..bee5910b
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/math-use-builtins-llrint.h
|
|
@@ -0,0 +1,10 @@
|
|
+#if __GNUC_PREREQ (13, 0)
|
|
+# define USE_LLRINT_BUILTIN 1
|
|
+# define USE_LLRINTF_BUILTIN 1
|
|
+#else
|
|
+# define USE_LLRINT_BUILTIN 0
|
|
+# define USE_LLRINTF_BUILTIN 0
|
|
+#endif
|
|
+
|
|
+#define USE_LLRINTL_BUILTIN 0
|
|
+#define USE_LLRINTF128_BUILTIN 0
|
|
diff --git a/sysdeps/loongarch/fpu/math-use-builtins-logb.h b/sysdeps/loongarch/fpu/math-use-builtins-logb.h
|
|
new file mode 100644
|
|
index 00000000..b1c3f30d
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/math-use-builtins-logb.h
|
|
@@ -0,0 +1,10 @@
|
|
+#if __GNUC_PREREQ (13, 0)
|
|
+# define USE_LOGB_BUILTIN 1
|
|
+# define USE_LOGBF_BUILTIN 1
|
|
+#else
|
|
+# define USE_LOGB_BUILTIN 0
|
|
+# define USE_LOGBF_BUILTIN 0
|
|
+#endif
|
|
+
|
|
+#define USE_LOGBL_BUILTIN 0
|
|
+#define USE_LOGBF128_BUILTIN 0
|
|
diff --git a/sysdeps/loongarch/fpu/math-use-builtins-lrint.h b/sysdeps/loongarch/fpu/math-use-builtins-lrint.h
|
|
new file mode 100644
|
|
index 00000000..7df8aac8
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/math-use-builtins-lrint.h
|
|
@@ -0,0 +1,10 @@
|
|
+#if __GNUC_PREREQ (13, 0)
|
|
+# define USE_LRINT_BUILTIN 1
|
|
+# define USE_LRINTF_BUILTIN 1
|
|
+#else
|
|
+# define USE_LRINT_BUILTIN 0
|
|
+# define USE_LRINTF_BUILTIN 0
|
|
+#endif
|
|
+
|
|
+#define USE_LRINTL_BUILTIN 0
|
|
+#define USE_LRINTF128_BUILTIN 0
|
|
diff --git a/sysdeps/loongarch/fpu/math-use-builtins-rint.h b/sysdeps/loongarch/fpu/math-use-builtins-rint.h
|
|
new file mode 100644
|
|
index 00000000..cd91482f
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/math-use-builtins-rint.h
|
|
@@ -0,0 +1,9 @@
|
|
+#if __GNUC_PREREQ (13, 0)
|
|
+# define USE_RINT_BUILTIN 1
|
|
+# define USE_RINTF_BUILTIN 1
|
|
+#else
|
|
+# define USE_RINT_BUILTIN 0
|
|
+# define USE_RINTF_BUILTIN 0
|
|
+#endif
|
|
+#define USE_RINTL_BUILTIN 0
|
|
+#define USE_RINTF128_BUILTIN 0
|
|
diff --git a/sysdeps/loongarch/fpu/s_finite.c b/sysdeps/loongarch/fpu/s_finite.c
|
|
new file mode 100644
|
|
index 00000000..a2e98f0b
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_finite.c
|
|
@@ -0,0 +1,30 @@
|
|
+/* finite(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <math.h>
|
|
+#include <fenv_private.h>
|
|
+
|
|
+int
|
|
+__finite (double x)
|
|
+{
|
|
+ int x_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ return x_cond & ~(_FCLASS_INF | _FCLASS_NAN);
|
|
+}
|
|
+hidden_def (__finite)
|
|
+weak_alias (__finite, finite)
|
|
diff --git a/sysdeps/loongarch/fpu/s_finitef.c b/sysdeps/loongarch/fpu/s_finitef.c
|
|
new file mode 100644
|
|
index 00000000..9ffab38a
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_finitef.c
|
|
@@ -0,0 +1,30 @@
|
|
+/* finitef(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <math.h>
|
|
+#include <fenv_private.h>
|
|
+
|
|
+int
|
|
+__finitef (float x)
|
|
+{
|
|
+ int x_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ return x_cond & ~(_FCLASS_INF | _FCLASS_NAN);
|
|
+}
|
|
+hidden_def (__finitef)
|
|
+weak_alias (__finitef, finitef)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fmaximum.c b/sysdeps/loongarch/fpu/s_fmaximum.c
|
|
new file mode 100644
|
|
index 00000000..af1c2bf0
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fmaximum.c
|
|
@@ -0,0 +1,40 @@
|
|
+/* fmaximum(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-double.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+double
|
|
+__fmaximum (double x, double y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond | y_cond) & _FCLASS_NAN))
|
|
+ return x * y;
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmax.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_double (__fmaximum, fmaximum)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fmaximum_mag.c b/sysdeps/loongarch/fpu/s_fmaximum_mag.c
|
|
new file mode 100644
|
|
index 00000000..5aed0603
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fmaximum_mag.c
|
|
@@ -0,0 +1,40 @@
|
|
+/* fmaximum_mag(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-double.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+double
|
|
+__fmaximum_mag (double x, double y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond | y_cond) & _FCLASS_NAN))
|
|
+ return x * y;
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmaxa.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_double (__fmaximum_mag, fmaximum_mag)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fmaximum_mag_num.c b/sysdeps/loongarch/fpu/s_fmaximum_mag_num.c
|
|
new file mode 100644
|
|
index 00000000..04c801b1
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fmaximum_mag_num.c
|
|
@@ -0,0 +1,48 @@
|
|
+/* fmaximum_mag_num(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-double.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+double
|
|
+__fmaximum_mag_num (double x, double y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond & _FCLASS_NAN) && !(y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmaxa.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return y;
|
|
+ }
|
|
+ else if (__glibc_unlikely(!(x_cond & _FCLASS_NAN) && (y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmaxa.d \t%0, %1, %2" : "=f" (y) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmaxa.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_double (__fmaximum_mag_num, fmaximum_mag_num)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fmaximum_mag_numf.c b/sysdeps/loongarch/fpu/s_fmaximum_mag_numf.c
|
|
new file mode 100644
|
|
index 00000000..a2e1aaf1
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fmaximum_mag_numf.c
|
|
@@ -0,0 +1,48 @@
|
|
+/* fmaximum_mag_numf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-float.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+float
|
|
+__fmaximum_mag_numf (float x, float y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond & _FCLASS_NAN) && !(y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmaxa.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return y;
|
|
+ }
|
|
+ else if (__glibc_unlikely(!(x_cond & _FCLASS_NAN) && (y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmaxa.s \t%0, %1, %2" : "=f" (y) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmaxa.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_float (__fmaximum_mag_num, fmaximum_mag_num)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fmaximum_magf.c b/sysdeps/loongarch/fpu/s_fmaximum_magf.c
|
|
new file mode 100644
|
|
index 00000000..29beb88c
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fmaximum_magf.c
|
|
@@ -0,0 +1,40 @@
|
|
+/* fmaximum_magf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-float.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+float
|
|
+__fmaximum_magf (float x, float y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond | y_cond) & _FCLASS_NAN))
|
|
+ return x * y;
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmaxa.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_float (__fmaximum_mag, fmaximum_mag)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fmaximum_num.c b/sysdeps/loongarch/fpu/s_fmaximum_num.c
|
|
new file mode 100644
|
|
index 00000000..142c6533
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fmaximum_num.c
|
|
@@ -0,0 +1,48 @@
|
|
+/* fmaximum_num(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-double.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+double
|
|
+__fmaximum_num (double x, double y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond & _FCLASS_NAN) && !(y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmax.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return y;
|
|
+ }
|
|
+ else if (__glibc_unlikely(!(x_cond & _FCLASS_NAN) && (y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmax.d \t%0, %1, %2" : "=f" (y) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmax.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_double (__fmaximum_num, fmaximum_num)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fmaximum_numf.c b/sysdeps/loongarch/fpu/s_fmaximum_numf.c
|
|
new file mode 100644
|
|
index 00000000..badf8f7e
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fmaximum_numf.c
|
|
@@ -0,0 +1,49 @@
|
|
+/* fmaximum_numf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-float.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+float
|
|
+__fmaximum_numf (float x, float y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond & _FCLASS_NAN) && !(y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmax.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return y;
|
|
+ }
|
|
+ else if (__glibc_unlikely(!(x_cond & _FCLASS_NAN) && (y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmax.s \t%0, %1, %2" : "=f" (y) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmax.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_float (__fmaximum_num, fmaximum_num)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fmaximumf.c b/sysdeps/loongarch/fpu/s_fmaximumf.c
|
|
new file mode 100644
|
|
index 00000000..da4dcb6a
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fmaximumf.c
|
|
@@ -0,0 +1,40 @@
|
|
+/* fmaximumf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-float.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+float
|
|
+__fmaximumf (float x, float y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond | y_cond) & _FCLASS_NAN))
|
|
+ return x * y;
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmax.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_float (__fmaximum, fmaximum)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fmaxmag.c b/sysdeps/loongarch/fpu/s_fmaxmag.c
|
|
new file mode 100644
|
|
index 00000000..8570a3ba
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fmaxmag.c
|
|
@@ -0,0 +1,29 @@
|
|
+/* fmaxmag(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-double.h>
|
|
+
|
|
+double
|
|
+__fmaxmag (double x, double y)
|
|
+{
|
|
+ asm volatile ("fmaxa.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+}
|
|
+libm_alias_double (__fmaxmag, fmaxmag)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fmaxmagf.c b/sysdeps/loongarch/fpu/s_fmaxmagf.c
|
|
new file mode 100644
|
|
index 00000000..413e7683
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fmaxmagf.c
|
|
@@ -0,0 +1,29 @@
|
|
+/* fmaxmagf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-float.h>
|
|
+
|
|
+float
|
|
+__fmaxmagf (float x, float y)
|
|
+{
|
|
+ asm volatile ("fmaxa.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+}
|
|
+libm_alias_float (__fmaxmag, fmaxmag)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fminimum.c b/sysdeps/loongarch/fpu/s_fminimum.c
|
|
new file mode 100644
|
|
index 00000000..e395ff7e
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fminimum.c
|
|
@@ -0,0 +1,40 @@
|
|
+/* fminimum(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-double.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+double
|
|
+__fminimum (double x, double y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond | y_cond) & _FCLASS_NAN))
|
|
+ return x * y;
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmin.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_double (__fminimum, fminimum)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fminimum_mag.c b/sysdeps/loongarch/fpu/s_fminimum_mag.c
|
|
new file mode 100644
|
|
index 00000000..f477498d
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fminimum_mag.c
|
|
@@ -0,0 +1,40 @@
|
|
+/* fminimum_mag(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-double.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+double
|
|
+__fminimum_mag (double x, double y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond | y_cond) & _FCLASS_NAN))
|
|
+ return x * y;
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmina.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_double (__fminimum_mag, fminimum_mag)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fminimum_mag_num.c b/sysdeps/loongarch/fpu/s_fminimum_mag_num.c
|
|
new file mode 100644
|
|
index 00000000..ff5aecd6
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fminimum_mag_num.c
|
|
@@ -0,0 +1,48 @@
|
|
+/* fminimum_mag_num(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-double.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+double
|
|
+__fminimum_mag_num (double x, double y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond & _FCLASS_NAN) && !(y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmina.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return y;
|
|
+ }
|
|
+ else if (__glibc_unlikely(!(x_cond & _FCLASS_NAN) && (y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmina.d \t%0, %1, %2" : "=f" (y) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmina.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_double (__fminimum_mag_num, fminimum_mag_num)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fminimum_mag_numf.c b/sysdeps/loongarch/fpu/s_fminimum_mag_numf.c
|
|
new file mode 100644
|
|
index 00000000..7c9a5dba
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fminimum_mag_numf.c
|
|
@@ -0,0 +1,48 @@
|
|
+/* fminimum_mag_numf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-float.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+float
|
|
+__fminimum_mag_numf (float x, float y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond & _FCLASS_NAN) && !(y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmina.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return y;
|
|
+ }
|
|
+ else if (__glibc_unlikely(!(x_cond & _FCLASS_NAN) && (y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmina.s \t%0, %1, %2" : "=f" (y) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmina.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_float (__fminimum_mag_num, fminimum_mag_num)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fminimum_magf.c b/sysdeps/loongarch/fpu/s_fminimum_magf.c
|
|
new file mode 100644
|
|
index 00000000..d0563fc2
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fminimum_magf.c
|
|
@@ -0,0 +1,40 @@
|
|
+/* fminimum_magf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-float.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+float
|
|
+__fminimum_magf (float x, float y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond | y_cond) & _FCLASS_NAN))
|
|
+ return x * y;
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmina.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_float (__fminimum_mag, fminimum_mag)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fminimum_num.c b/sysdeps/loongarch/fpu/s_fminimum_num.c
|
|
new file mode 100644
|
|
index 00000000..5d9680be
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fminimum_num.c
|
|
@@ -0,0 +1,48 @@
|
|
+/* fminimum_num(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-double.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+double
|
|
+__fminimum_num (double x, double y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond & _FCLASS_NAN) && !(y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmin.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return y;
|
|
+ }
|
|
+ else if (__glibc_unlikely(!(x_cond & _FCLASS_NAN) && (y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmin.d \t%0, %1, %2" : "=f" (y) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmin.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_double (__fminimum_num, fminimum_num)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fminimum_numf.c b/sysdeps/loongarch/fpu/s_fminimum_numf.c
|
|
new file mode 100644
|
|
index 00000000..1610fe32
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fminimum_numf.c
|
|
@@ -0,0 +1,48 @@
|
|
+/* fminimum_numf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-float.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+float
|
|
+__fminimum_numf (float x, float y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond & _FCLASS_NAN) && !(y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmin.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return y;
|
|
+ }
|
|
+ else if (__glibc_unlikely(!(x_cond & _FCLASS_NAN) && (y_cond & _FCLASS_NAN)))
|
|
+ {
|
|
+ asm volatile ("fmin.s \t%0, %1, %2" : "=f" (y) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmin.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_float (__fminimum_num, fminimum_num)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fminimumf.c b/sysdeps/loongarch/fpu/s_fminimumf.c
|
|
new file mode 100644
|
|
index 00000000..680c5e7e
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fminimumf.c
|
|
@@ -0,0 +1,40 @@
|
|
+/* fminimumf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-float.h>
|
|
+#include <fpu_control.h>
|
|
+
|
|
+float
|
|
+__fminimumf (float x, float y)
|
|
+{
|
|
+ int x_cond;
|
|
+ int y_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (y_cond) : "f" (y));
|
|
+
|
|
+ if (__glibc_unlikely((x_cond | y_cond) & _FCLASS_NAN))
|
|
+ return x * y;
|
|
+ else
|
|
+ {
|
|
+ asm volatile ("fmin.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+ }
|
|
+}
|
|
+libm_alias_float (__fminimum, fminimum)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fminmag.c b/sysdeps/loongarch/fpu/s_fminmag.c
|
|
new file mode 100644
|
|
index 00000000..2badf3d3
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fminmag.c
|
|
@@ -0,0 +1,29 @@
|
|
+/* fminmag(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-double.h>
|
|
+
|
|
+double
|
|
+__fminmag (double x, double y)
|
|
+{
|
|
+ asm volatile ("fmina.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+}
|
|
+libm_alias_double (__fminmag, fminmag)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fminmagf.c b/sysdeps/loongarch/fpu/s_fminmagf.c
|
|
new file mode 100644
|
|
index 00000000..4d625312
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fminmagf.c
|
|
@@ -0,0 +1,29 @@
|
|
+/* fminmagf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+#include <libm-alias-float.h>
|
|
+
|
|
+float
|
|
+__fminmagf (float x, float y)
|
|
+{
|
|
+ asm volatile ("fmina.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
|
|
+ return x;
|
|
+}
|
|
+libm_alias_float (__fminmag, fminmag)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fpclassify.c b/sysdeps/loongarch/fpu/s_fpclassify.c
|
|
new file mode 100644
|
|
index 00000000..3f4d95da
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fpclassify.c
|
|
@@ -0,0 +1,38 @@
|
|
+/* fpclassify(). LoongArch version.
|
|
+ Copyright (C) 2017-2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <math.h>
|
|
+#include <fenv_private.h>
|
|
+
|
|
+int
|
|
+__fpclassify (double x)
|
|
+{
|
|
+ int cls;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (cls) : "f" (x));
|
|
+
|
|
+ if (__glibc_likely (!!(cls & _FCLASS_NORM)))
|
|
+ return FP_NORMAL;
|
|
+ if (__glibc_likely (!!(cls & _FCLASS_ZERO)))
|
|
+ return FP_ZERO;
|
|
+ if (__glibc_likely (!!(cls & _FCLASS_SUBNORM)))
|
|
+ return FP_SUBNORMAL;
|
|
+ if (__glibc_likely (!!(cls & _FCLASS_INF)))
|
|
+ return FP_INFINITE;
|
|
+ return FP_NAN;
|
|
+}
|
|
+libm_hidden_def (__fpclassify)
|
|
diff --git a/sysdeps/loongarch/fpu/s_fpclassifyf.c b/sysdeps/loongarch/fpu/s_fpclassifyf.c
|
|
new file mode 100644
|
|
index 00000000..b7c8b253
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_fpclassifyf.c
|
|
@@ -0,0 +1,38 @@
|
|
+/* Copyright (C) 2017-2022 Free Software Foundation, Inc.
|
|
+
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <math.h>
|
|
+#include <fenv_private.h>
|
|
+
|
|
+int
|
|
+__fpclassifyf (float x)
|
|
+{
|
|
+ int cls;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (cls) : "f" (x));
|
|
+
|
|
+ if (__glibc_likely (!!(cls & _FCLASS_NORM)))
|
|
+ return FP_NORMAL;
|
|
+ if (__glibc_likely (!!(cls & _FCLASS_ZERO)))
|
|
+ return FP_ZERO;
|
|
+ if (__glibc_likely (!!(cls & _FCLASS_SUBNORM)))
|
|
+ return FP_SUBNORMAL;
|
|
+ if (__glibc_likely (!!(cls & _FCLASS_INF)))
|
|
+ return FP_INFINITE;
|
|
+ return FP_NAN;
|
|
+}
|
|
+libm_hidden_def (__fpclassifyf)
|
|
diff --git a/sysdeps/loongarch/fpu/s_isinf.c b/sysdeps/loongarch/fpu/s_isinf.c
|
|
new file mode 100644
|
|
index 00000000..c7a67841
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_isinf.c
|
|
@@ -0,0 +1,30 @@
|
|
+/* isinf(). LoongArch version.
|
|
+ Copyright (C) 2017-2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <math.h>
|
|
+#include <fenv_private.h>
|
|
+
|
|
+int
|
|
+__isinf (double x)
|
|
+{
|
|
+ int x_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ return -((x_cond & _FCLASS_MINF) ? 1 : 0) | ((x_cond & _FCLASS_PINF) ? 1 : 0);
|
|
+}
|
|
+hidden_def (__isinf)
|
|
+weak_alias (__isinf, isinf)
|
|
diff --git a/sysdeps/loongarch/fpu/s_isinff.c b/sysdeps/loongarch/fpu/s_isinff.c
|
|
new file mode 100644
|
|
index 00000000..dcb4e04e
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_isinff.c
|
|
@@ -0,0 +1,30 @@
|
|
+/* isinff(). LoongArch version.
|
|
+ Copyright (C) 2017-2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <math.h>
|
|
+#include <fenv_private.h>
|
|
+
|
|
+int
|
|
+__isinff (float x)
|
|
+{
|
|
+ int x_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ return -((x_cond & _FCLASS_MINF) ? 1 : 0) | ((x_cond & _FCLASS_PINF) ? 1 : 0);
|
|
+}
|
|
+hidden_def (__isinff)
|
|
+weak_alias (__isinff, isinff)
|
|
diff --git a/sysdeps/loongarch/fpu/s_isnan.c b/sysdeps/loongarch/fpu/s_isnan.c
|
|
new file mode 100644
|
|
index 00000000..62bb2e2f
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_isnan.c
|
|
@@ -0,0 +1,31 @@
|
|
+/* isnan(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <math.h>
|
|
+#include <fenv_private.h>
|
|
+
|
|
+int
|
|
+__isnan (double x)
|
|
+{
|
|
+ int x_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+
|
|
+ return (x_cond & _FCLASS_NAN) != 0;
|
|
+}
|
|
+hidden_def (__isnan)
|
|
+weak_alias (__isnan, isnan)
|
|
diff --git a/sysdeps/loongarch/fpu/s_isnanf.c b/sysdeps/loongarch/fpu/s_isnanf.c
|
|
new file mode 100644
|
|
index 00000000..bbdedb84
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_isnanf.c
|
|
@@ -0,0 +1,31 @@
|
|
+/* isnanf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <math.h>
|
|
+#include <fenv_private.h>
|
|
+
|
|
+int
|
|
+__isnanf (float x)
|
|
+{
|
|
+ int x_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+
|
|
+ return (x_cond & _FCLASS_NAN) != 0;
|
|
+}
|
|
+hidden_def (__isnanf)
|
|
+weak_alias (__isnanf, isnanf)
|
|
diff --git a/sysdeps/loongarch/fpu/s_issignaling.c b/sysdeps/loongarch/fpu/s_issignaling.c
|
|
new file mode 100644
|
|
index 00000000..4fe0e2b7
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_issignaling.c
|
|
@@ -0,0 +1,29 @@
|
|
+/* issignaling(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <math.h>
|
|
+#include <fenv_private.h>
|
|
+
|
|
+int
|
|
+__issignaling (double x)
|
|
+{
|
|
+ int x_cond;
|
|
+ asm volatile ("fclass.d \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ return (x_cond & _FCLASS_SNAN) != 0;
|
|
+}
|
|
+libm_hidden_def (__issignaling)
|
|
diff --git a/sysdeps/loongarch/fpu/s_issignalingf.c b/sysdeps/loongarch/fpu/s_issignalingf.c
|
|
new file mode 100644
|
|
index 00000000..d82abb0e
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_issignalingf.c
|
|
@@ -0,0 +1,29 @@
|
|
+/* issignalingf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <math.h>
|
|
+#include <fenv_private.h>
|
|
+
|
|
+int
|
|
+__issignalingf (float x)
|
|
+{
|
|
+ int x_cond;
|
|
+ asm volatile ("fclass.s \t%0, %1" : "=f" (x_cond) : "f" (x));
|
|
+ return (x_cond & _FCLASS_SNAN) != 0;
|
|
+}
|
|
+libm_hidden_def (__issignalingf)
|
|
diff --git a/sysdeps/loongarch/fpu/s_scalbn.c b/sysdeps/loongarch/fpu/s_scalbn.c
|
|
new file mode 100644
|
|
index 00000000..c03e81a3
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_scalbn.c
|
|
@@ -0,0 +1,29 @@
|
|
+/* scalbn(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+
|
|
+double
|
|
+__scalbn (double x, int fn)
|
|
+{
|
|
+ double tmp;
|
|
+ asm volatile ("movgr2fr.d \t%0, %1" : "=f" (tmp) : "r" (fn));
|
|
+ asm volatile ("fscaleb.d \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (tmp));
|
|
+ return x;
|
|
+}
|
|
diff --git a/sysdeps/loongarch/fpu/s_scalbnf.c b/sysdeps/loongarch/fpu/s_scalbnf.c
|
|
new file mode 100644
|
|
index 00000000..15e64280
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/fpu/s_scalbnf.c
|
|
@@ -0,0 +1,29 @@
|
|
+/* scalbnf(). LoongArch version.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#define NO_MATH_REDIRECT
|
|
+#include <math.h>
|
|
+
|
|
+float
|
|
+__scalbnf (float x, int fn)
|
|
+{
|
|
+ float tmp;
|
|
+ asm volatile ("movgr2fr.w \t%0, %1" : "=f" (tmp) : "r" (fn));
|
|
+ asm volatile ("fscaleb.s \t%0, %1, %2" : "=f" (x) : "f" (x), "f" (tmp));
|
|
+ return x;
|
|
+}
|
|
diff --git a/sysdeps/loongarch/fpu_control.h b/sysdeps/loongarch/fpu_control.h
|
|
index 1cccc933..13436335 100644
|
|
--- a/sysdeps/loongarch/fpu_control.h
|
|
+++ b/sysdeps/loongarch/fpu_control.h
|
|
@@ -51,6 +51,17 @@
|
|
|
|
#include <features.h>
|
|
|
|
+#ifdef __loongarch_soft_float
|
|
+
|
|
+#define _FPU_RESERVED 0xffffffff
|
|
+#define _FPU_DEFAULT 0x00000000
|
|
+typedef unsigned int fpu_control_t;
|
|
+#define _FPU_GETCW(cw) (cw) = 0
|
|
+#define _FPU_SETCW(cw) (void) (cw)
|
|
+extern fpu_control_t __fpu_control;
|
|
+
|
|
+#else /* __loongarch_soft_float */
|
|
+
|
|
/* Masks for interrupts. */
|
|
#define _FPU_MASK_V 0x10 /* Invalid operation */
|
|
#define _FPU_MASK_Z 0x08 /* Division by zero */
|
|
@@ -86,4 +97,23 @@ extern void __loongarch_fpu_setcw (fpu_control_t) __THROW;
|
|
/* Default control word set at startup. */
|
|
extern fpu_control_t __fpu_control;
|
|
|
|
+# define _FCLASS_SNAN (1 << 0)
|
|
+# define _FCLASS_QNAN (1 << 1)
|
|
+# define _FCLASS_MINF (1 << 2)
|
|
+# define _FCLASS_MNORM (1 << 3)
|
|
+# define _FCLASS_MSUBNORM (1 << 4)
|
|
+# define _FCLASS_MZERO (1 << 5)
|
|
+# define _FCLASS_PINF (1 << 6)
|
|
+# define _FCLASS_PNORM (1 << 7)
|
|
+# define _FCLASS_PSUBNORM (1 << 8)
|
|
+# define _FCLASS_PZERO (1 << 9)
|
|
+
|
|
+# define _FCLASS_ZERO (_FCLASS_MZERO | _FCLASS_PZERO)
|
|
+# define _FCLASS_SUBNORM (_FCLASS_MSUBNORM | _FCLASS_PSUBNORM)
|
|
+# define _FCLASS_NORM (_FCLASS_MNORM | _FCLASS_PNORM)
|
|
+# define _FCLASS_INF (_FCLASS_MINF | _FCLASS_PINF)
|
|
+# define _FCLASS_NAN (_FCLASS_SNAN | _FCLASS_QNAN)
|
|
+
|
|
+#endif /* __loongarch_soft_float */
|
|
+
|
|
#endif /* fpu_control.h */
|
|
diff --git a/sysdeps/loongarch/lp64/libm-test-ulps b/sysdeps/loongarch/lp64/libm-test-ulps
|
|
index c711531e..770bf36b 100644
|
|
--- a/sysdeps/loongarch/lp64/libm-test-ulps
|
|
+++ b/sysdeps/loongarch/lp64/libm-test-ulps
|
|
@@ -1046,6 +1046,7 @@ ldouble: 8
|
|
|
|
Function: "hypot":
|
|
double: 1
|
|
+float: 1
|
|
ldouble: 1
|
|
|
|
Function: "hypot_downward":
|
|
diff --git a/sysdeps/loongarch/nofpu/Implies b/sysdeps/loongarch/nofpu/Implies
|
|
new file mode 100644
|
|
index 00000000..abcbadb2
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/nofpu/Implies
|
|
@@ -0,0 +1 @@
|
|
+ieee754/soft-fp
|
|
diff --git a/sysdeps/loongarch/nofpu/math-tests-exceptions.h b/sysdeps/loongarch/nofpu/math-tests-exceptions.h
|
|
new file mode 100644
|
|
index 00000000..b22bb01d
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/nofpu/math-tests-exceptions.h
|
|
@@ -0,0 +1,28 @@
|
|
+/* Configuration for math tests: support for exceptions.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#ifndef LOONGARCH_NOFPU_MATH_TESTS_EXCEPTIONS_H
|
|
+#define LOONGARCH_NOFPU_MATH_TESTS_EXCEPTIONS_H 1
|
|
+
|
|
+/* We support setting floating-point exception flags on hard-float
|
|
+ targets. These are not supported on soft-float targets. */
|
|
+#define EXCEPTION_TESTS_float 0
|
|
+#define EXCEPTION_TESTS_double 0
|
|
+#define EXCEPTION_TESTS_long_double 0
|
|
+
|
|
+#endif /* math-tests-exceptions.h. */
|
|
diff --git a/sysdeps/loongarch/nofpu/math-tests-rounding.h b/sysdeps/loongarch/nofpu/math-tests-rounding.h
|
|
new file mode 100644
|
|
index 00000000..5322e481
|
|
--- /dev/null
|
|
+++ b/sysdeps/loongarch/nofpu/math-tests-rounding.h
|
|
@@ -0,0 +1,27 @@
|
|
+/* Configuration for math tests: rounding mode support.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#ifndef LOONGARCH_NOFPU_MATH_TESTS_ROUNDING_H
|
|
+#define LOONGARCH_NOFPU_MATH_TESTS_ROUNDING_H 1
|
|
+
|
|
+/* On soft-float targets we only support the "to nearest" rounding mode. */
|
|
+#define ROUNDING_TESTS_float(MODE) ((MODE) == FE_TONEAREST)
|
|
+#define ROUNDING_TESTS_double(MODE) ((MODE) == FE_TONEAREST)
|
|
+#define ROUNDING_TESTS_long_double(MODE) ((MODE) == FE_TONEAREST)
|
|
+
|
|
+#endif /* math-tests-rounding.h. */
|
|
diff --git a/sysdeps/loongarch/preconfigure b/sysdeps/loongarch/preconfigure
|
|
index 118963cd..f2d1a0d8 100644
|
|
--- a/sysdeps/loongarch/preconfigure
|
|
+++ b/sysdeps/loongarch/preconfigure
|
|
@@ -12,7 +12,6 @@ loongarch*)
|
|
case "$float_abi" in
|
|
soft)
|
|
abi_flen=0
|
|
- as_fn_error 1 "loongarch does not yet support soft floating-point ABI!!" "$LINENO" 5
|
|
;;
|
|
single)
|
|
as_fn_error 1 "glibc does not yet support the single floating-point ABI!!" "$LINENO" 5
|
|
diff --git a/sysdeps/loongarch/preconfigure.ac b/sysdeps/loongarch/preconfigure.ac
|
|
index 1aba743c..67e43570 100644
|
|
--- a/sysdeps/loongarch/preconfigure.ac
|
|
+++ b/sysdeps/loongarch/preconfigure.ac
|
|
@@ -12,7 +12,6 @@ loongarch*)
|
|
case "$float_abi" in
|
|
soft)
|
|
abi_flen=0
|
|
- AC_MSG_ERROR([loongarch does not yet support soft floating-point ABI!!], 1)
|
|
;;
|
|
single)
|
|
AC_MSG_ERROR([glibc does not yet support the single floating-point ABI!!], 1)
|
|
diff --git a/sysdeps/loongarch/setjmp.S b/sysdeps/loongarch/setjmp.S
|
|
index 3afb9f39..9b1cdea4 100644
|
|
--- a/sysdeps/loongarch/setjmp.S
|
|
+++ b/sysdeps/loongarch/setjmp.S
|
|
@@ -29,8 +29,15 @@ ENTRY (setjmp)
|
|
END (setjmp)
|
|
|
|
ENTRY (__sigsetjmp)
|
|
+#ifdef PTR_MANGLE
|
|
+ PTR_MANGLE (t0, ra, t1)
|
|
+ REG_S t0, a0, 0*SZREG
|
|
+ PTR_MANGLE2 (t0, sp, t1)
|
|
+ REG_S t0, a0, 1*SZREG
|
|
+#else
|
|
REG_S ra, a0, 0*SZREG
|
|
REG_S sp, a0, 1*SZREG
|
|
+#endif
|
|
REG_S x, a0, 2*SZREG
|
|
REG_S fp, a0, 3*SZREG
|
|
REG_S s0, a0, 4*SZREG
|
|
@@ -43,6 +50,7 @@ ENTRY (__sigsetjmp)
|
|
REG_S s7, a0, 11*SZREG
|
|
REG_S s8, a0, 12*SZREG
|
|
|
|
+#ifndef __loongarch_soft_float
|
|
FREG_S $f24, a0, 13*SZREG + 0*SZFREG
|
|
FREG_S $f25, a0, 13*SZREG + 1*SZFREG
|
|
FREG_S $f26, a0, 13*SZREG + 2*SZFREG
|
|
@@ -51,6 +59,7 @@ ENTRY (__sigsetjmp)
|
|
FREG_S $f29, a0, 13*SZREG + 5*SZFREG
|
|
FREG_S $f30, a0, 13*SZREG + 6*SZFREG
|
|
FREG_S $f31, a0, 13*SZREG + 7*SZFREG
|
|
+#endif
|
|
|
|
#if !IS_IN (libc) && IS_IN(rtld)
|
|
li.w v0, 0
|
|
diff --git a/sysdeps/loongarch/start.S b/sysdeps/loongarch/start.S
|
|
index bf5728b3..83aeacb1 100644
|
|
--- a/sysdeps/loongarch/start.S
|
|
+++ b/sysdeps/loongarch/start.S
|
|
@@ -44,9 +44,20 @@ ENTRY (ENTRY_POINT)
|
|
cfi_undefined (1)
|
|
or a5, a0, zero /* rtld_fini */
|
|
|
|
-/* We must get symbol main through GOT table, since main may not be local.
|
|
- For instance: googletest defines main in dynamic library. */
|
|
- la.got a0, t0, main
|
|
+#if ENABLE_STATIC_PIE
|
|
+/* For static PIE, the GOT cannot be used in _start because the GOT entries are
|
|
+ offsets instead of real addresses before __libc_start_main.
|
|
+ __libc_start_main and/or main may be not local, so we rely on the linker to
|
|
+ produce PLT entries for them. GNU ld >= 2.40 supports this. */
|
|
+# define LA la.pcrel
|
|
+#else
|
|
+/* Old GNU ld (< 2.40) cannot handle PC relative address against a non-local
|
|
+ function correctly. We deem these old linkers failing to support static PIE
|
|
+ and load the addresses from GOT. */
|
|
+# define LA la.got
|
|
+#endif
|
|
+
|
|
+ LA a0, t0, main
|
|
REG_L a1, sp, 0
|
|
ADDI a2, sp, SZREG
|
|
|
|
@@ -57,9 +68,9 @@ ENTRY (ENTRY_POINT)
|
|
move a4, zero /* used to be fini */
|
|
or a6, sp, zero /* stack_end */
|
|
|
|
- la.got ra, t0, __libc_start_main
|
|
+ LA ra, t0, __libc_start_main
|
|
jirl ra, ra, 0
|
|
|
|
- la.got ra, t0, abort
|
|
+ LA ra, t0, abort
|
|
jirl ra, ra, 0
|
|
END (ENTRY_POINT)
|
|
diff --git a/sysdeps/loongarch/sys/asm.h b/sysdeps/loongarch/sys/asm.h
|
|
index b41ee596..83ee3f67 100644
|
|
--- a/sysdeps/loongarch/sys/asm.h
|
|
+++ b/sysdeps/loongarch/sys/asm.h
|
|
@@ -31,6 +31,7 @@
|
|
#define SLLI slli.d
|
|
#define ADDI addi.d
|
|
#define ADD add.d
|
|
+#define SUB sub.d
|
|
#define BSTRINS bstrins.d
|
|
#define LI li.d
|
|
#define FREG_L fld.d
|
|
diff --git a/sysdeps/unix/sysv/linux/loongarch/Makefile b/sysdeps/unix/sysv/linux/loongarch/Makefile
|
|
index 91bd3580..c84a1762 100644
|
|
--- a/sysdeps/unix/sysv/linux/loongarch/Makefile
|
|
+++ b/sysdeps/unix/sysv/linux/loongarch/Makefile
|
|
@@ -1,3 +1,12 @@
|
|
ifeq ($(subdir),stdlib)
|
|
gen-as-const-headers += ucontext_i.sym
|
|
endif
|
|
+
|
|
+abi-variants := lp64s lp64d
|
|
+
|
|
+ifeq (,$(filter $(default-abi),$(abi-variants)))
|
|
+$(error Unknown ABI $(default-abi), must be one of $(abi-variants))
|
|
+endif
|
|
+
|
|
+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/bits/shmlba.h b/sysdeps/unix/sysv/linux/loongarch/bits/shmlba.h
|
|
new file mode 100644
|
|
index 00000000..3c171ef7
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sysv/linux/loongarch/bits/shmlba.h
|
|
@@ -0,0 +1,24 @@
|
|
+/* Define SHMLBA. LoongArch version.
|
|
+ Copyright (C) 2023 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#ifndef _SYS_SHM_H
|
|
+# error "Never use <bits/shmlba.h> directly; include <sys/shm.h> instead."
|
|
+#endif
|
|
+
|
|
+/* Segment low boundary address multiple. */
|
|
+#define SHMLBA 0x10000
|
|
diff --git a/sysdeps/unix/sysv/linux/loongarch/configure b/sysdeps/unix/sysv/linux/loongarch/configure
|
|
index 60a41030..28216c16 100644
|
|
--- a/sysdeps/unix/sysv/linux/loongarch/configure
|
|
+++ b/sysdeps/unix/sysv/linux/loongarch/configure
|
|
@@ -151,11 +151,56 @@ if test $libc_cv_loongarch_int_abi = no; then
|
|
as_fn_error $? "Unable to determine integer ABI" "$LINENO" 5
|
|
fi
|
|
|
|
+libc_cv_loongarch_float_abi=no
|
|
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
+/* end confdefs.h. */
|
|
+#ifdef __loongarch_double_float
|
|
+ yes
|
|
+ #endif
|
|
+
|
|
+_ACEOF
|
|
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
|
|
+ $EGREP "yes" >/dev/null 2>&1; then :
|
|
+ libc_cv_loongarch_float_abi=d
|
|
+fi
|
|
+rm -f conftest*
|
|
+
|
|
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
+/* end confdefs.h. */
|
|
+#ifdef __loongarch_soft_float
|
|
+ yes
|
|
+ #endif
|
|
+
|
|
+_ACEOF
|
|
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
|
|
+ $EGREP "yes" >/dev/null 2>&1; then :
|
|
+ libc_cv_loongarch_float_abi=s
|
|
+fi
|
|
+rm -f conftest*
|
|
+
|
|
+if test "$libc_cv_loongarch_float_abi" = no; then
|
|
+ as_fn_error $? "Unable to determine floating-point ABI" "$LINENO" 5
|
|
+fi
|
|
+
|
|
config_vars="$config_vars
|
|
-default-abi = $libc_cv_loongarch_int_abi"
|
|
+default-abi = $libc_cv_loongarch_int_abi$libc_cv_loongarch_float_abi"
|
|
|
|
-case $libc_cv_loongarch_int_abi in
|
|
-lp64)
|
|
+case $libc_cv_loongarch_int_abi$libc_cv_loongarch_float_abi in
|
|
+lp64s)
|
|
+ test -n "$libc_cv_slibdir" ||
|
|
+case "$prefix" in
|
|
+/usr | /usr/)
|
|
+ libc_cv_slibdir='/lib64/sf'
|
|
+ libc_cv_rtlddir='/lib64'
|
|
+ if test "$libdir" = '${exec_prefix}/lib'; then
|
|
+ libdir='${exec_prefix}/lib64/sf';
|
|
+ # Locale data can be shared between 32-bit and 64-bit libraries.
|
|
+ libc_cv_complocaledir='${exec_prefix}/lib/locale'
|
|
+ fi
|
|
+ ;;
|
|
+esac
|
|
+ ;;
|
|
+lp64d)
|
|
test -n "$libc_cv_slibdir" ||
|
|
case "$prefix" in
|
|
/usr | /usr/)
|
|
diff --git a/sysdeps/unix/sysv/linux/loongarch/configure.ac b/sysdeps/unix/sysv/linux/loongarch/configure.ac
|
|
index 7de1e95f..04e9150a 100644
|
|
--- a/sysdeps/unix/sysv/linux/loongarch/configure.ac
|
|
+++ b/sysdeps/unix/sysv/linux/loongarch/configure.ac
|
|
@@ -11,10 +11,26 @@ if test $libc_cv_loongarch_int_abi = no; then
|
|
AC_MSG_ERROR([Unable to determine integer ABI])
|
|
fi
|
|
|
|
-LIBC_CONFIG_VAR([default-abi], [$libc_cv_loongarch_int_abi])
|
|
+libc_cv_loongarch_float_abi=no
|
|
+AC_EGREP_CPP(yes, [#ifdef __loongarch_double_float
|
|
+ yes
|
|
+ #endif
|
|
+ ],libc_cv_loongarch_float_abi=d)
|
|
+AC_EGREP_CPP(yes, [#ifdef __loongarch_soft_float
|
|
+ yes
|
|
+ #endif
|
|
+ ],libc_cv_loongarch_float_abi=s)
|
|
+if test "$libc_cv_loongarch_float_abi" = no; then
|
|
+ AC_MSG_ERROR([Unable to determine floating-point ABI])
|
|
+fi
|
|
+
|
|
+LIBC_CONFIG_VAR([default-abi], [$libc_cv_loongarch_int_abi$libc_cv_loongarch_float_abi])
|
|
|
|
-case $libc_cv_loongarch_int_abi in
|
|
-lp64)
|
|
+case $libc_cv_loongarch_int_abi$libc_cv_loongarch_float_abi in
|
|
+lp64s)
|
|
+ LIBC_SLIBDIR_RTLDDIR([lib64/sf], [lib64])
|
|
+ ;;
|
|
+lp64d)
|
|
LIBC_SLIBDIR_RTLDDIR([lib64], [lib64])
|
|
;;
|
|
esac
|
|
diff --git a/sysdeps/unix/sysv/linux/loongarch/dl-cache.h b/sysdeps/unix/sysv/linux/loongarch/dl-cache.h
|
|
new file mode 100644
|
|
index 00000000..05219c62
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sysv/linux/loongarch/dl-cache.h
|
|
@@ -0,0 +1,82 @@
|
|
+/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
|
|
+ Copyright (C) 2022-2023 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <ldconfig.h>
|
|
+#include <assert.h>
|
|
+
|
|
+#if defined __loongarch_double_float
|
|
+# define _DL_CACHE_DEFAULT_ID (FLAG_LARCH_FLOAT_ABI_DOUBLE | FLAG_ELF_LIBC6)
|
|
+#else
|
|
+# define _DL_CACHE_DEFAULT_ID (FLAG_LARCH_FLOAT_ABI_SOFT | FLAG_ELF_LIBC6)
|
|
+#endif
|
|
+
|
|
+#define _dl_cache_check_flags(flags) \
|
|
+ ((flags) == _DL_CACHE_DEFAULT_ID)
|
|
+
|
|
+/* If given a path to one of our library directories, adds every library
|
|
+ directory via add_dir (), otherwise just adds the giver directory. On
|
|
+ LoongArch, libraries can be found in paths ending in:
|
|
+ - /lib64
|
|
+ - /lib64/sf
|
|
+ so this will add all of those paths. */
|
|
+
|
|
+#define add_system_dir(dir) \
|
|
+ do \
|
|
+ { \
|
|
+ static const char* lib_dirs[] = { \
|
|
+ "/lib64", \
|
|
+ "/lib64/sf", \
|
|
+ NULL, \
|
|
+ }; \
|
|
+ const size_t lib_len = sizeof ("/lib") - 1; \
|
|
+ size_t len = strlen (dir); \
|
|
+ char path[len + 6]; \
|
|
+ const char **ptr; \
|
|
+ \
|
|
+ memcpy (path, dir, len + 1); \
|
|
+ \
|
|
+ for (ptr = lib_dirs; *ptr != NULL; ptr++) \
|
|
+ { \
|
|
+ const char *lib_dir = *ptr; \
|
|
+ size_t dir_len = strlen (lib_dir); \
|
|
+ \
|
|
+ if (len >= dir_len \
|
|
+ && !memcmp (path + len - dir_len, lib_dir, dir_len)) \
|
|
+ { \
|
|
+ len -= dir_len - lib_len; \
|
|
+ path[len] = '\0'; \
|
|
+ break; \
|
|
+ } \
|
|
+ } \
|
|
+ add_dir (path); \
|
|
+ if (len >= lib_len \
|
|
+ && !memcmp (path + len - lib_len, "/lib", lib_len)) \
|
|
+ for (ptr = lib_dirs; *ptr != NULL; ptr++) \
|
|
+ { \
|
|
+ const char *lib_dir = *ptr; \
|
|
+ size_t dir_len = strlen (lib_dir); \
|
|
+ \
|
|
+ assert (dir_len >= lib_len); \
|
|
+ memcpy (path + len, lib_dir + lib_len, \
|
|
+ dir_len - lib_len + 1); \
|
|
+ add_dir (path); \
|
|
+ } \
|
|
+ } while (0)
|
|
+
|
|
+
|
|
+#include_next <dl-cache.h>
|
|
diff --git a/sysdeps/unix/sysv/linux/loongarch/gettimeofday.c b/sysdeps/unix/sysv/linux/loongarch/gettimeofday.c
|
|
new file mode 100644
|
|
index 00000000..ee35a086
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sysv/linux/loongarch/gettimeofday.c
|
|
@@ -0,0 +1,22 @@
|
|
+/* gettimeofday -- Get the current time of day.
|
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
|
+
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ 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>
|
|
diff --git a/sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed b/sysdeps/unix/sysv/linux/loongarch/ldd-rewrite.sed
|
|
index f8976fd2..cdbe5c3d 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\)\(/[^/]*\)\(-loongarch\)\(64\|32\)\(\.so\.[0-9.]*\)[[:blank:]]*$_\1"\2\4\7 \264\4-loongarch64\7 \232\4-loongarch32\7"_
|
|
+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"_
|
|
diff --git a/sysdeps/unix/sysv/linux/loongarch/readelflib.c b/sysdeps/unix/sysv/linux/loongarch/readelflib.c
|
|
new file mode 100644
|
|
index 00000000..e3461289
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sysv/linux/loongarch/readelflib.c
|
|
@@ -0,0 +1,76 @@
|
|
+/* Support for reading ELF files.
|
|
+ Copyright (C) 2022-2023 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+
|
|
+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);
|
|
+
|
|
+#define SUPPORTED_ELF_FLAGS \
|
|
+ (EF_LARCH_ABI_DOUBLE_FLOAT | EF_LARCH_ABI_SOFT_FLOAT)
|
|
+
|
|
+/* Returns 0 if everything is ok, != 0 in case of error. */
|
|
+int
|
|
+process_elf_file (const char *file_name, const char *lib, int *flag,
|
|
+ unsigned int *isa_level, char **soname, void *file_contents,
|
|
+ size_t file_length)
|
|
+{
|
|
+ ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
|
|
+ Elf64_Ehdr *elf64_header = (Elf64_Ehdr *) elf_header;
|
|
+ int ret;
|
|
+ long flags;
|
|
+
|
|
+ /* LoongArch libraries are always libc.so.6+. */
|
|
+ *flag = FLAG_ELF_LIBC6;
|
|
+
|
|
+ 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;
|
|
+
|
|
+ /* LoongArch linkers encode the floating point ABI as part of the ELF headers. */
|
|
+ switch (flags & SUPPORTED_ELF_FLAGS)
|
|
+ {
|
|
+ case EF_LARCH_ABI_SOFT_FLOAT:
|
|
+ *flag |= FLAG_LARCH_FLOAT_ABI_SOFT;
|
|
+ break;
|
|
+ case EF_LARCH_ABI_DOUBLE_FLOAT:
|
|
+ *flag |= FLAG_LARCH_FLOAT_ABI_DOUBLE;
|
|
+ break;
|
|
+ default:
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ /* If there are any other ELF flags set then glibc doesn't support this
|
|
+ library. */
|
|
+ if (flags & ~SUPPORTED_ELF_FLAGS)
|
|
+ return 1;
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+#undef __ELF_NATIVE_CLASS
|
|
+#undef process_elf_file
|
|
+#define process_elf_file process_elf64_file
|
|
+#define __ELF_NATIVE_CLASS 64
|
|
+#include "elf/readelflib.c"
|
|
diff --git a/sysdeps/unix/sysv/linux/loongarch/shlib-versions b/sysdeps/unix/sysv/linux/loongarch/shlib-versions
|
|
index dc2220b4..5f40e7f5 100644
|
|
--- a/sysdeps/unix/sysv/linux/loongarch/shlib-versions
|
|
+++ b/sysdeps/unix/sysv/linux/loongarch/shlib-versions
|
|
@@ -2,6 +2,8 @@ DEFAULT GLIBC_2.36
|
|
|
|
%if 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
|
|
%else
|
|
%error cannot determine ABI
|
|
%endif
|
|
diff --git a/sysdeps/unix/sysv/linux/loongarch/sysdep.h b/sysdeps/unix/sysv/linux/loongarch/sysdep.h
|
|
index e4c8fc29..f4a1d23a 100644
|
|
--- a/sysdeps/unix/sysv/linux/loongarch/sysdep.h
|
|
+++ b/sysdeps/unix/sysv/linux/loongarch/sysdep.h
|
|
@@ -116,6 +116,7 @@
|
|
/* List of system calls which are supported as vsyscalls. */
|
|
#define HAVE_CLOCK_GETRES64_VSYSCALL "__vdso_clock_getres"
|
|
#define HAVE_CLOCK_GETTIME64_VSYSCALL "__vdso_clock_gettime"
|
|
+#define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday"
|
|
#define HAVE_GETCPU_VSYSCALL "__vdso_getcpu"
|
|
|
|
#define HAVE_CLONE3_WRAPPER 1
|
|
@@ -313,8 +314,64 @@ extern long int __syscall_error (long int neg_errno);
|
|
|
|
#endif /* ! __ASSEMBLER__ */
|
|
|
|
-/* Pointer mangling is not supported. */
|
|
-#define PTR_MANGLE(var) (void) (var)
|
|
-#define PTR_DEMANGLE(var) (void) (var)
|
|
+/* Pointer mangling is supported for LoongArch. */
|
|
+
|
|
+/* Load a got-relative EXPR into G, using T.
|
|
+ Note G and T are register names. */
|
|
+#define LD_GLOBAL(G, EXPR) \
|
|
+ la.global G, EXPR; \
|
|
+ REG_L G, G, 0;
|
|
+
|
|
+/* Load a pc-relative EXPR into G, using T.
|
|
+ Note G and T are register names. */
|
|
+#define LD_PCREL(G, EXPR) \
|
|
+ la.pcrel G, EXPR; \
|
|
+ REG_L G, G, 0;
|
|
+
|
|
+#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); \
|
|
+ PTR_MANGLE2 (dst, src, guard);
|
|
+#define PTR_DEMANGLE(dst, src, guard) \
|
|
+ LD_PCREL (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) \
|
|
+ xor dst, src, guard;
|
|
+#define PTR_DEMANGLE2(dst, src, guard) \
|
|
+ PTR_MANGLE2 (dst, src, guard);
|
|
+#else
|
|
+extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
|
|
+#define PTR_MANGLE(var) \
|
|
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
|
|
+#define PTR_DEMANGLE(var) PTR_MANGLE (var)
|
|
+#endif
|
|
+
|
|
+#else
|
|
+
|
|
+#ifdef __ASSEMBLER__
|
|
+#define PTR_MANGLE(dst, src, guard) \
|
|
+ LD_GLOBAL (guard, __pointer_chk_guard); \
|
|
+ PTR_MANGLE2 (dst, src, guard);
|
|
+#define PTR_DEMANGLE(dst, src, guard) \
|
|
+ LD_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) \
|
|
+ xor dst, src, guard;
|
|
+#define PTR_DEMANGLE2(dst, src, guard) \
|
|
+ PTR_MANGLE2 (dst, src, guard);
|
|
+#else
|
|
+extern uintptr_t __pointer_chk_guard attribute_relro;
|
|
+#define PTR_MANGLE(var) \
|
|
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
|
|
+#define PTR_DEMANGLE(var) PTR_MANGLE (var)
|
|
+#endif
|
|
+
|
|
+#endif
|
|
|
|
#endif /* linux/loongarch/sysdep.h */
|
|
diff --git a/sysdeps/unix/sysv/linux/syscall.c b/sysdeps/unix/sysv/linux/syscall.c
|
|
index 7303ba71..8cb0b66b 100644
|
|
--- a/sysdeps/unix/sysv/linux/syscall.c
|
|
+++ b/sysdeps/unix/sysv/linux/syscall.c
|
|
@@ -33,7 +33,7 @@ syscall (long int number, ...)
|
|
long int a5 = va_arg (args, long int);
|
|
va_end (args);
|
|
|
|
- int r = INTERNAL_SYSCALL_NCS_CALL (number, a0, a1, a2, a3, a4, a5);
|
|
+ long int r = INTERNAL_SYSCALL_NCS_CALL (number, a0, a1, a2, a3, a4, a5);
|
|
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (r)))
|
|
{
|
|
__set_errno (-r);
|
|
--
|
|
2.33.0
|
|
|