1 Star 0 Fork 163

junhe_arm/glibc

forked from src-openEuler/glibc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0005-Sw64-Generic-math.h-and-soft-fp-Routines.patch 11.35 KB
一键复制 编辑 原始数据 按行查看 历史
swcompiler 提交于 2024-12-17 04:02 +08:00 . Sw64: Add Sw64 ISA support
From cdac1f3a59bcd4bdad675f7c352aefa03d237f96 Mon Sep 17 00:00:00 2001
From: swcompiler <lc@wxiat.com>
Date: Fri, 29 Nov 2024 14:19:24 +0800
Subject: [PATCH 05/23] Sw64: Generic <math.h> and soft-fp Routines
---
sysdeps/sw_64/fpu/bits/fenv.h | 140 ++++++++++++++++++++++++++++++++++
sysdeps/sw_64/local-soft-fp.h | 67 ++++++++++++++++
sysdeps/sw_64/sfp-machine.h | 105 +++++++++++++++++++++++++
sysdeps/sw_64/tininess.h | 1 +
4 files changed, 313 insertions(+)
create mode 100644 sysdeps/sw_64/fpu/bits/fenv.h
create mode 100644 sysdeps/sw_64/local-soft-fp.h
create mode 100644 sysdeps/sw_64/sfp-machine.h
create mode 100644 sysdeps/sw_64/tininess.h
diff --git a/sysdeps/sw_64/fpu/bits/fenv.h b/sysdeps/sw_64/fpu/bits/fenv.h
new file mode 100644
index 00000000..ec5dfb8d
--- /dev/null
+++ b/sysdeps/sw_64/fpu/bits/fenv.h
@@ -0,0 +1,140 @@
+/* Copyright (C) 1997-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 _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+/* Define the bits representing the exception.
+
+ Note that these are the bit positions as defined by the OSF/1
+ ieee_{get,set}_control_word interface and not by the hardware fpcr.
+
+ See the Sw_64 Architecture Handbook section 4.7.7.3 for details,
+ but in summary, trap shadows mean the hardware register can acquire
+ extra exception bits so for proper IEEE support the tracking has to
+ be done in software -- in this case with kernel support.
+
+ As to why the system call interface isn't in the same format as
+ the hardware register, only those crazy folks at DEC can tell you. */
+
+enum
+{
+#ifdef __USE_GNU
+ FE_DENORMAL =
+# define FE_DENORMAL (1 << 22)
+ FE_DENORMAL,
+#endif
+
+ FE_INEXACT =
+#define FE_INEXACT (1 << 21)
+ FE_INEXACT,
+
+ FE_UNDERFLOW =
+#define FE_UNDERFLOW (1 << 20)
+ FE_UNDERFLOW,
+
+ FE_OVERFLOW =
+#define FE_OVERFLOW (1 << 19)
+ FE_OVERFLOW,
+
+ FE_DIVBYZERO =
+#define FE_DIVBYZERO (1 << 18)
+ FE_DIVBYZERO,
+
+ FE_INVALID =
+#define FE_INVALID (1 << 17)
+ FE_INVALID,
+
+ FE_ALL_EXCEPT =
+#define FE_ALL_EXCEPT (0x3f << 17)
+ FE_ALL_EXCEPT
+};
+
+/* Sw_64 chips support all four defined rouding modes.
+
+ Note that code must be compiled to use dynamic rounding (/d) instructions
+ to see these changes. For gcc this is -mfp-rounding-mode=d; for DEC cc
+ this is -fprm d. The default for both is static rounding to nearest.
+
+ These are shifted down 58 bits from the hardware fpcr because the
+ functions are declared to take integers. */
+
+enum
+{
+ FE_TOWARDZERO =
+#define FE_TOWARDZERO 0
+ FE_TOWARDZERO,
+
+ FE_DOWNWARD =
+#define FE_DOWNWARD 1
+ FE_DOWNWARD,
+
+ FE_TONEAREST =
+#define FE_TONEAREST 2
+ FE_TONEAREST,
+
+ FE_UPWARD =
+#define FE_UPWARD 3
+ FE_UPWARD,
+};
+
+#ifdef __USE_GNU
+/* On later hardware, and later kernels for earlier hardware, we can forcibly
+ underflow denormal inputs and outputs. This can speed up certain programs
+ significantly, usually without affecting accuracy. */
+enum
+{
+ FE_MAP_DMZ = 1UL << 12, /* Map denorm inputs to zero */
+# define FE_MAP_DMZ FE_MAP_DMZ
+
+ FE_MAP_UMZ = 1UL << 13, /* Map underflowed outputs to zero */
+# define FE_MAP_UMZ FE_MAP_UMZ
+};
+#endif
+
+/* Type representing exception flags. */
+typedef unsigned long int fexcept_t;
+
+/* Type representing floating-point environment. */
+typedef unsigned long int fenv_t;
+
+/* If the default argument is used we use this value. Note that due to
+ architecture-specified page mappings, no user-space pointer will ever
+ have its two high bits set. Co-opt one. */
+#define FE_DFL_ENV ((const fenv_t *) 0x8800000000000000UL)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exceptions are masked. */
+# define FE_NOMASK_ENV ((const fenv_t *) 0x880000000000003eUL)
+
+/* Floating-point environment with (processor-dependent) non-IEEE floating
+ point. In this case, mapping denormals to zero. */
+# define FE_NONIEEE_ENV ((const fenv_t *) 0x8800000000003000UL)
+#endif
+
+/* The system calls to talk to the kernel's FP code. */
+extern unsigned long int __ieee_get_fp_control (void) __THROW;
+extern void __ieee_set_fp_control (unsigned long int __value) __THROW;
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT_C2X)
+/* Type representing floating-point control modes. */
+typedef unsigned long int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) 0x8800000000000000UL)
+#endif
diff --git a/sysdeps/sw_64/local-soft-fp.h b/sysdeps/sw_64/local-soft-fp.h
new file mode 100644
index 00000000..aab93c30
--- /dev/null
+++ b/sysdeps/sw_64/local-soft-fp.h
@@ -0,0 +1,67 @@
+#include <stdlib.h>
+#include <soft-fp.h>
+#include <quad.h>
+
+/* Helpers for the Ots functions which receive long double arguments
+ in two integer registers, and return values in $16+$17. */
+
+#define AXP_UNPACK_RAW_Q(X, val) \
+ do \
+ { \
+ union _FP_UNION_Q _flo; \
+ _flo.longs.a = val##l; \
+ _flo.longs.b = val##h; \
+ FP_UNPACK_RAW_QP (X, &_flo); \
+ } \
+ while (0)
+
+#define AXP_UNPACK_SEMIRAW_Q(X, val) \
+ do \
+ { \
+ union _FP_UNION_Q _flo; \
+ _flo.longs.a = val##l; \
+ _flo.longs.b = val##h; \
+ FP_UNPACK_SEMIRAW_QP (X, &_flo); \
+ } \
+ while (0)
+
+#define AXP_UNPACK_Q(X, val) \
+ do \
+ { \
+ AXP_UNPACK_RAW_Q (X, val); \
+ _FP_UNPACK_CANONICAL (Q, 2, X); \
+ } \
+ while (0)
+
+#define AXP_PACK_RAW_Q(val, X) FP_PACK_RAW_QP (&val##_flo, X)
+
+#define AXP_PACK_SEMIRAW_Q(val, X) \
+ do \
+ { \
+ _FP_PACK_SEMIRAW (Q, 2, X); \
+ AXP_PACK_RAW_Q (val, X); \
+ } \
+ while (0)
+
+#define AXP_PACK_Q(val, X) \
+ do \
+ { \
+ _FP_PACK_CANONICAL (Q, 2, X); \
+ AXP_PACK_RAW_Q (val, X); \
+ } \
+ while (0)
+
+#define AXP_DECL_RETURN_Q(X) union _FP_UNION_Q X##_flo
+
+/* ??? We don't have a real way to tell the compiler that we're wanting
+ to return values in $16+$17. Instead use a volatile asm to make sure
+ that the values are live, and just hope that nothing kills the values
+ in between here and the end of the function. */
+#define AXP_RETURN_Q(X) \
+ do \
+ { \
+ register long r16 __asm__ ("16") = X##_flo.longs.a; \
+ register long r17 __asm__ ("17") = X##_flo.longs.b; \
+ asm volatile ("" : : "r"(r16), "r"(r17)); \
+ } \
+ while (0)
diff --git a/sysdeps/sw_64/sfp-machine.h b/sysdeps/sw_64/sfp-machine.h
new file mode 100644
index 00000000..119e50fc
--- /dev/null
+++ b/sysdeps/sw_64/sfp-machine.h
@@ -0,0 +1,105 @@
+/* Machine-dependent software floating-point definitions.
+ Sw_64 userland IEEE 128-bit version.
+ Copyright (C) 2004-2023 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com),
+ Jakub Jelinek (jj@ultra.linux.cz) and
+ David S. Miller (davem@redhat.com).
+
+ 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 <fenv_libc.h>
+
+#define _FP_W_TYPE_SIZE 64
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
+
+#define _FP_MUL_MEAT_S(R, X, Y) _FP_MUL_MEAT_1_imm (_FP_WFRACBITS_S, R, X, Y)
+#define _FP_MUL_MEAT_D(R, X, Y) \
+ _FP_MUL_MEAT_1_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm)
+#define _FP_MUL_MEAT_Q(R, X, Y) \
+ _FP_MUL_MEAT_2_wide (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R, X, Y) \
+ _FP_DIV_MEAT_1_imm (S, R, X, Y, _FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R, X, Y) _FP_DIV_MEAT_1_udiv_norm (D, R, X, Y)
+#define _FP_DIV_MEAT_Q(R, X, Y) _FP_DIV_MEAT_2_udiv (Q, R, X, Y)
+
+#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1)
+#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1
+#define _FP_NANSIGN_S 0
+#define _FP_NANSIGN_D 0
+#define _FP_NANSIGN_Q 0
+
+#define _FP_KEEPNANFRACP 1
+#define _FP_QNANNEGATEDP 0
+
+/* Sw_64 Architecture Handbook, 4.7.10.4 sez that we should prefer any
+ type of NaN in Fb, then Fa. */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do \
+ { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc (R, X); \
+ R##_c = FP_CLS_NAN; \
+ } \
+ while (0)
+
+/* Rounding mode settings. */
+#define FP_RND_NEAREST FE_TONEAREST
+#define FP_RND_ZERO FE_TOWARDZERO
+#define FP_RND_PINF FE_UPWARD
+#define FP_RND_MINF FE_DOWNWARD
+
+/* Obtain the current rounding mode. It's given as an argument to
+ all the Ots functions, with 4 meaning "dynamic". */
+#define FP_ROUNDMODE _round
+
+/* Exception flags. */
+#define FP_EX_INVALID FE_INVALID
+#define FP_EX_OVERFLOW FE_OVERFLOW
+#define FP_EX_UNDERFLOW FE_UNDERFLOW
+#define FP_EX_DIVZERO FE_DIVBYZERO
+#define FP_EX_INEXACT FE_INEXACT
+
+#define _FP_TININESS_AFTER_ROUNDING 1
+
+#define FP_INIT_ROUNDMODE \
+ do \
+ { \
+ if (__builtin_expect (_round == 4, 0)) \
+ { \
+ unsigned long t; \
+ __asm__ __volatile__("excb; rfpcr %0" : "=f"(t)); \
+ _round = (t >> FPCR_ROUND_SHIFT) & 3; \
+ } \
+ } \
+ while (0)
+
+/* We copy the libm function into libc for soft-fp. */
+extern int __feraiseexcept (int __excepts) attribute_hidden;
+
+#define FP_HANDLE_EXCEPTIONS \
+ do \
+ { \
+ if (__builtin_expect (_fex, 0)) \
+ __feraiseexcept (_fex); \
+ } \
+ while (0)
+
+#define FP_TRAPPING_EXCEPTIONS \
+ ((__ieee_get_fp_control () & SWCR_ENABLE_MASK) << SWCR_ENABLE_SHIFT)
diff --git a/sysdeps/sw_64/tininess.h b/sysdeps/sw_64/tininess.h
new file mode 100644
index 00000000..90956c35
--- /dev/null
+++ b/sysdeps/sw_64/tininess.h
@@ -0,0 +1 @@
+#define TININESS_AFTER_ROUNDING 1
--
2.25.1
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/junhe_arm/glibc.git
git@gitee.com:junhe_arm/glibc.git
junhe_arm
glibc
glibc
master

搜索帮助