diff options
533 files changed, 12820 insertions, 7499 deletions
diff --git a/COPYING.LIB b/COPYING.LIB index 8add30ad5..1f7c8cc65 100644 --- a/COPYING.LIB +++ b/COPYING.LIB @@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. - + Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a @@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. - + GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @@ -158,7 +158,7 @@ Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - + 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 @@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. - + Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. @@ -267,7 +267,7 @@ Library will still fall under Section 6.) distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. - + 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work @@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. - + 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined @@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. - + 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or @@ -422,7 +422,7 @@ conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. - + 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is @@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS - + How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest @@ -276,7 +276,7 @@ cmd_compile.mi= $(cmd_compile.m:-c=-E -dD) $(UCLIBC_EXTRA_CPPFLAGS) cmd_compile-m = $(CC) $^ -c -o $@ $(CFLAGS) $(CFLAGS-$(suffix $@)) $(CFLAGS-$(notdir $(@D))) $(CFLAGS-$(notdir $@)) $(sort $(foreach d,$(^:$(top_srcdir)=),$(collect_multi_flags))) cmd_strip = $(STRIPTOOL) $(STRIP_FLAGS) $^ cmd_t_strip = $(STRIPTOOL) $(STRIP_FLAGS) $@ -cmd_ar = $(AR) $(ARFLAGS) $@ $(call objects_with_syms,,$^) +cmd_ar = $(AR) $(ARFLAGS) $@ @$@.list define do_ln @$(disp_ln) @@ -317,6 +317,7 @@ hcompile.u= @$(disp_hcompile.u); $(cmd_hcompile.u) hcompile.o= @$(disp_hcompile.o); $(cmd_hcompile.o) define do_ar + @$(file >$@.list,$(call objects_with_syms,,$^)) @$(disp_ar) ; $(cmd_ar) @$(do_t_strip) endef @@ -1,7 +1,7 @@ # Rules.mak for uClibc-ng # # Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org> -# Copyright (C) 2015-2024 Waldemar Brodkorb <wbx@uclibc-ng.org> +# Copyright (C) 2015-2025 Waldemar Brodkorb <wbx@uclibc-ng.org> # # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # @@ -128,7 +128,7 @@ export RUNTIME_PREFIX DEVEL_PREFIX KERNEL_HEADERS MULTILIB_DIR # Now config hard core MAJOR_VERSION := 1 MINOR_VERSION := 0 -SUBLEVEL := 47 +SUBLEVEL := 54 EXTRAVERSION := VERSION := $(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL) ABI_VERSION := $(MAJOR_VERSION) @@ -312,10 +312,6 @@ endif endif endif -ifeq ($(TARGET_ARCH),aarch64) -CPU_CFLAGS-y += -ftls-model=initial-exec -endif - $(eval $(call check-gcc-var,-std=gnu99)) CPU_CFLAGS-y += $(CFLAG_-std=gnu99) @@ -336,8 +332,6 @@ $(eval $(call check-gcc-var,-ffunction-sections)) # Some nice CPU specific optimizations ifeq ($(TARGET_ARCH),i386) -$(eval $(call check-gcc-var,-fomit-frame-pointer)) - OPTIMIZATION += $(CFLAG_-fomit-frame-pointer) ifeq ($(CONFIG_386)$(CONFIG_486)$(CONFIG_586),y) # TODO: Change this to a gcc version check. This bug @@ -522,6 +516,10 @@ ifeq ($(TARGET_ARCH),c6x) CPU_LDFLAGS-y += $(CPU_CFLAGS) endif +ifeq ($(TARGET_ARCH),xtensa) + CPU_CFLAGS-$(UCLIBC_FORMAT_FDPIC_ELF) += -mfdpic +endif + $(eval $(call check-gcc-var,$(PIEFLAG_NAME))) PIEFLAG := $(CFLAG_$(PIEFLAG_NAME)) ifeq ($(PIEFLAG),) @@ -606,6 +604,7 @@ CFLAGS := $(XWARNINGS) $(CPU_CFLAGS) $(SSP_CFLAGS) \ -nostdinc -I$(top_builddir)include \ -I$(top_srcdir)include -include libc-symbols.h \ -I$(top_srcdir)libc/sysdeps/linux/$(TARGET_ARCH) \ + -I$(top_builddir)libc/sysdeps/linux/$(TARGET_ARCH) \ -I$(top_srcdir)libc/sysdeps/linux \ -I$(top_srcdir)ldso/ldso/$(TARGET_ARCH) \ -I$(top_srcdir)ldso/include -I. @@ -662,6 +661,15 @@ endif ifneq ($(strip $(UCLIBC_EXTRA_CFLAGS)),"") CFLAGS += $(call qstrip,$(UCLIBC_EXTRA_CFLAGS)) endif +ifeq ($(TARGET_ARCH),i386) +CFLAGS += -fno-omit-frame-pointer +endif +ifeq ($(TARGET_ARCH),bfin) +CFLAGS += -Wno-implicit-function-declaration +endif +ifeq ($(TARGET_ARCH),frv) +CFLAGS += -Wno-implicit-function-declaration +endif ifneq ($(strip $(UCLIBC_EXTRA_LDFLAGS)),"") LDFLAGS += $(call qstrip,$(UCLIBC_EXTRA_LDFLAGS)) endif diff --git a/extra/Configs/Config.aarch64 b/extra/Configs/Config.aarch64 index d666cc595..6074878f2 100644 --- a/extra/Configs/Config.aarch64 +++ b/extra/Configs/Config.aarch64 @@ -13,6 +13,7 @@ config FORCE_OPTIONS_FOR_ARCH select ARCH_ANY_ENDIAN select ARCH_HAS_MMU select ARCH_USE_MMU + select ARCH_VDSO_SUPPORT select UCLIBC_HAS_FPU choice diff --git a/extra/Configs/Config.arm b/extra/Configs/Config.arm index 0d02e3f10..ea8ab4895 100644 --- a/extra/Configs/Config.arm +++ b/extra/Configs/Config.arm @@ -13,6 +13,7 @@ config FORCE_OPTIONS_FOR_ARCH select ARCH_ANY_ENDIAN select ARCH_HAS_UCONTEXT select ARCH_HAS_DEPRECATED_SYSCALLS + select ARCH_VDSO_SUPPORT config CONFIG_ARM_EABI bool "Build for EABI" diff --git a/extra/Configs/Config.i386 b/extra/Configs/Config.i386 index c928ac1a2..c2a9a6e93 100644 --- a/extra/Configs/Config.i386 +++ b/extra/Configs/Config.i386 @@ -14,6 +14,7 @@ config FORCE_OPTIONS_FOR_ARCH select ARCH_HAS_MMU select ARCH_HAS_UCONTEXT select ARCH_HAS_DEPRECATED_SYSCALLS + select ARCH_VDSO_SUPPORT choice prompt "Target x86 Processor Family" diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 2d1692ba5..454b6ddb8 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -336,7 +336,8 @@ config STATIC_PIE depends on DOPIC && !UCLIBC_FORMAT_FDPIC_ELF && \ (TARGET_aarch64 || TARGET_arm || TARGET_i386 || \ TARGET_m68k || TARGET_mips || TARGET_powerpc || \ - TARGET_riscv64 || TARGET_x86_64 || TARGET_xtensa) + TARGET_riscv32 || TARGET_riscv64 || TARGET_x86_64 \ + || TARGET_xtensa) config ARCH_HAS_NO_SHARED bool @@ -544,7 +545,7 @@ config LDSO_LD_LIBRARY_PATH If unsure, simply say Y here. config UCLIBC_CTOR_DTOR - bool + bool "Support global constructors and destructors" default y help If you wish to build uClibc with support for global constructor @@ -594,7 +595,6 @@ config UCLIBC_HAS_LINUXTHREADS # linuxthreads need nanosleep() select UCLIBC_HAS_REALTIME depends on !TARGET_aarch64 && \ - !TARGET_riscv32 && \ !TARGET_metag help If you want to compile uClibc with Linuxthreads support, then answer Y. @@ -615,7 +615,7 @@ config UCLIBC_HAS_THREADS_NATIVE !TARGET_h8300 && \ !TARGET_hppa && \ !TARGET_ia64 && \ - (ARCH_USE_MMU || TARGET_arm) + (ARCH_USE_MMU || TARGET_arm || TARGET_xtensa) help If you want to compile uClibc with NPTL support, then answer Y. @@ -1028,6 +1028,7 @@ config UCLIBC_USE_TIME64 bool "Use *time64 syscalls instead of 32bit ones (if possible)" depends on TARGET_arc || \ TARGET_arm || \ + TARGET_csky || \ TARGET_i386 || \ TARGET_m68k || \ TARGET_microblaze || \ @@ -1039,7 +1040,7 @@ config UCLIBC_USE_TIME64 TARGET_sh || \ TARGET_xtensa # TODO: add support for other architectures - default n + default y help Replace 32bit syscalls to their 64/time64 analog if possible. diff --git a/extra/Configs/Config.in.arch b/extra/Configs/Config.in.arch index 4bcf3ff3f..24c0db157 100644 --- a/extra/Configs/Config.in.arch +++ b/extra/Configs/Config.in.arch @@ -13,14 +13,14 @@ choice config UCLIBC_FORMAT_ELF bool "ELF (using ELF_FDPIC loader)" depends on !ARCH_USE_MMU && (TARGET_arm || TARGET_m68k || \ - TARGET_riscv64) + TARGET_riscv32 || TARGET_riscv64) select DOPIC select STATIC_PIE select ARCH_HAS_NO_SHARED select HAVE_LDSO config UCLIBC_FORMAT_FDPIC_ELF bool "FDPIC ELF" - depends on !ARCH_USE_MMU && (TARGET_bfin || TARGET_frv || TARGET_arm) + depends on !ARCH_USE_MMU && (TARGET_bfin || TARGET_frv || TARGET_arm || TARGET_xtensa) select DOPIC config UCLIBC_FORMAT_DSBT_ELF bool "DBST ELF" @@ -34,13 +34,6 @@ config UCLIBC_FORMAT_FLAT_SEP_DATA bool "STATIC FLAT (sep-data)" depends on !ARCH_USE_MMU && !TARGET_frv select ARCH_HAS_NO_LDSO -config UCLIBC_FORMAT_SHARED_FLAT - bool "SHARED FLAT" - depends on !ARCH_USE_MMU && !TARGET_frv - select ARCH_HAS_NO_LDSO - help - Pick this one if you are using uClinux and wish to build - uClibc as a flat-format shared library. endchoice endif if ARCH_USE_MMU @@ -55,24 +48,6 @@ config ARCH_HAS_DEPRECATED_SYSCALLS this symbol controls whether there is support for these threading libraries or not. -config UCLIBC_SHARED_FLAT_ID - int "Shared library ID" - default 1 - depends on UCLIBC_FORMAT_SHARED_FLAT - help - When using flat shared libraries, every library has a unique - system-wide identifier. Identifier 0 is reserved for - executables and true shared libraries have identifiers - starting at 1. The maximum shared library identifier is - determined by the kernel and is usually 3. Shared library - N must be available on the target system as "/lib/libN.so". - - When a shared C library is used, it usually has identifier 1, - but you can use this option to select a different identifier - if you need to. - - - # # Endian Format # @@ -189,9 +164,20 @@ config UCLIBC_HAS_FENV bool "Enable C99 Floating-point environment" depends on UCLIBC_HAS_FLOATS depends on TARGET_i386 || \ + TARGET_aarch64 || \ + TARGET_arc || \ + TARGET_arm || \ + TARGET_csky || \ + TARGET_m68k || \ TARGET_metag || \ + TARGET_mips || \ TARGET_nds32 || \ + TARGET_or1k || \ (TARGET_powerpc && CONFIG_E500) || \ + TARGET_riscv32 || \ + TARGET_riscv64 || \ + (TARGET_sh && (CONFIG_SH4 || CONFIG_SH4A)) || \ + TARGET_sparc || \ TARGET_x86_64 help If you want the uClibc math library to contain the C99 floating diff --git a/extra/Configs/Config.nds32 b/extra/Configs/Config.nds32 index 8bac9e679..2ed6a32b7 100644 --- a/extra/Configs/Config.nds32 +++ b/extra/Configs/Config.nds32 @@ -11,6 +11,7 @@ config FORCE_OPTIONS_FOR_ARCH bool default y select ARCH_ANY_ENDIAN + select ARCH_HAS_DEPRECATED_SYSCALLS select ARCH_HAS_MMU select ARCH_HAS_UCONTEXT diff --git a/extra/config/lxdialog/check-lxdialog.sh b/extra/config/lxdialog/check-lxdialog.sh index 9d2a4c585..66bfcb549 100644 --- a/extra/config/lxdialog/check-lxdialog.sh +++ b/extra/config/lxdialog/check-lxdialog.sh @@ -43,7 +43,7 @@ trap "rm -f $tmp" 0 1 2 3 15 check() { $cc -x c - -o $tmp 2>/dev/null <<'EOF' #include CURSES_LOC -main() {} +int main() {} EOF if [ $? != 0 ]; then echo " *** Unable to find the ncurses libraries or the" 1>&2 diff --git a/extra/config/zconf.tab.c_shipped b/extra/config/zconf.tab.c_shipped index 208f20087..a2d7a7543 100644 --- a/extra/config/zconf.tab.c_shipped +++ b/extra/config/zconf.tab.c_shipped @@ -1067,7 +1067,7 @@ int yydebug; # define YYMAXDEPTH 10000 #endif - + #if YYERROR_VERBOSE @@ -1278,7 +1278,7 @@ yysyntax_error (char *yyresult, int yystate, int yychar) } } #endif /* YYERROR_VERBOSE */ - + /*-----------------------------------------------. | Release the memory associated to this symbol. | diff --git a/extra/scripts/unifdef.c b/extra/scripts/unifdef.c index 0f059205f..cfe34377a 100644 --- a/extra/scripts/unifdef.c +++ b/extra/scripts/unifdef.c @@ -201,7 +201,7 @@ static int depth; /* current #if nesting */ static int delcount; /* count of deleted lines */ static unsigned blankcount; /* count of blank lines */ static unsigned blankmax; /* maximum recent blankcount */ -static bool constexpr; /* constant #if expression */ +static bool const_expr; /* constant #if expression */ static bool zerosyms; /* to format symdepth output */ static bool firstsym; /* ditto */ @@ -951,7 +951,7 @@ static long prec(const struct ops *ops) /* * Function for evaluating the innermost parts of expressions, * viz. !expr (expr) number defined(symbol) symbol - * We reset the constexpr flag in the last two cases. + * We reset the const_expr flag in the last two cases. */ static Linetype eval_unary(const struct ops *ops, long *valp, const char **cpp) @@ -1011,7 +1011,7 @@ eval_unary(const struct ops *ops, long *valp, const char **cpp) *valp = (value[sym] != NULL); lt = *valp ? LT_TRUE : LT_FALSE; } - constexpr = false; + const_expr = false; } else if (!endsym(*cp)) { debug("eval%d symbol", prec(ops)); sym = findsym(&cp); @@ -1028,7 +1028,7 @@ eval_unary(const struct ops *ops, long *valp, const char **cpp) lt = *valp ? LT_TRUE : LT_FALSE; cp = skipargs(cp); } - constexpr = false; + const_expr = false; } else { debug("eval%d bad expr", prec(ops)); return (LT_ERROR); @@ -1088,10 +1088,10 @@ ifeval(const char **cpp) long val = 0; debug("eval %s", *cpp); - constexpr = killconsts ? false : true; + const_expr = killconsts ? false : true; ret = eval_table(eval_ops, &val, cpp); debug("eval = %d", val); - return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret); + return (const_expr ? LT_IF : ret == LT_ERROR ? LT_IF : ret); } /* diff --git a/include/argp.h b/include/argp.h index 8e8674296..d67723521 100644 --- a/include/argp.h +++ b/include/argp.h @@ -46,12 +46,14 @@ /* This feature is available in gcc versions 2.5 and later. */ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || defined(__STRICT_ANSI__) # define __attribute__(Spec) /* empty */ +# define __UCLIBC_ATTRIBUTE_FALLBACK__ # endif /* The __-protected variants of `format' and `printf' attributes are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || defined(__STRICT_ANSI__) # define __format__ format # define __printf__ printf +# define __UCLIBC_PRINTF_FALLBACK__ # endif #endif @@ -71,7 +73,7 @@ typedef int error_t; # define __error_t_defined #endif - + #ifdef __cplusplus extern "C" { #endif @@ -145,7 +147,7 @@ struct argp_option distinguish these two cases, -x should probably be marked OPTION_NO_USAGE. */ #define OPTION_NO_USAGE 0x10 - + struct argp; /* fwd declare this type */ struct argp_state; /* " */ struct argp_child; /* " */ @@ -283,7 +285,7 @@ struct argp suppressed. */ #define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005 #define ARGP_KEY_HELP_ARGS_DOC 0x2000006 /* Argument doc string. */ - + /* When an argp has a non-zero CHILDREN field, it should point to a vector of argp_child structures, each of which describes a subsidiary argp. */ struct argp_child @@ -308,7 +310,7 @@ struct argp_child (merging the child's grouping levels with the parents). */ int group; }; - + /* Parsing state. This is provided to parsing functions called by argp, which may examine and, as noted, modify fields. */ struct argp_state @@ -356,7 +358,7 @@ struct argp_state void *pstate; /* Private, for use by argp. */ }; - + /* Flags for argp_parse (note that the defaults are those that are convenient for program command line parsing): */ @@ -412,7 +414,7 @@ extern error_t argp_parse (__const struct argp *__restrict __argp, int __argc, char **__restrict __argv, unsigned __flags, int *__restrict __arg_index, void *__restrict __input); - + /* Global variables. */ /* If defined or set by the user program to a non-zero value, then a default @@ -441,7 +443,7 @@ extern __const char *argp_program_bug_address; If not defined or set by the user program, this defaults to EX_USAGE from <sysexits.h>. */ extern error_t argp_err_exit_status; - + /* Flags for argp_help. */ #define ARGP_HELP_USAGE 0x01 /* a Usage: message. */ #define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */ @@ -476,7 +478,7 @@ extern error_t argp_err_exit_status; extern void argp_help (__const struct argp *__restrict __argp, FILE *__restrict __stream, unsigned __flags, char *__restrict __name); - + /* The following routines are intended to be called from within an argp parsing routine (thus taking an argp_state structure as the first argument). They may or may not print an error message and exit, depending @@ -526,7 +528,7 @@ extern int __option_is_end (__const struct argp_option *__opt) __THROW; extern void *__argp_input (__const struct argp *__restrict __argp, __const struct argp_state *__restrict __state) __THROW; - + #ifdef __USE_EXTERN_INLINES # ifndef ARGP_EI @@ -562,4 +564,13 @@ __NTH (__option_is_end (__const struct argp_option *__opt)) } #endif +#ifdef __UCLIBC_ATTRIBUTE_FALLBACK__ +# undef __attribute__ +#endif + +#ifdef __UCLIBC_PRINTF_FALLBACK__ +# undef __format__ +# undef __printf__ +#endif + #endif /* argp.h */ diff --git a/include/atomic.h b/include/atomic.h index 267aff5d5..3adcfbc5f 100644 --- a/include/atomic.h +++ b/include/atomic.h @@ -54,15 +54,15 @@ and following args. */ #define __atomic_val_bysize(pre, post, mem, ...) \ ({ \ - __typeof (*mem) __atg1_result; \ + __typeof ((__typeof (*(mem))) *(mem)) __atg1_result; \ if (sizeof (*mem) == 1) \ - __atg1_result = pre##_8_##post (mem, __VA_ARGS__); \ + __atg1_result = (__typeof ((__typeof (*(mem))) *(mem))) pre##_8_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 2) \ - __atg1_result = pre##_16_##post (mem, __VA_ARGS__); \ + __atg1_result = (__typeof ((__typeof (*(mem))) *(mem))) pre##_16_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 4) \ - __atg1_result = pre##_32_##post (mem, __VA_ARGS__); \ + __atg1_result = (__typeof ((__typeof (*(mem))) *(mem))) pre##_32_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 8) \ - __atg1_result = pre##_64_##post (mem, __VA_ARGS__); \ + __atg1_result = (__typeof ((__typeof (*(mem))) *(mem))) pre##_64_##post (mem, __VA_ARGS__); \ else \ abort (); \ __atg1_result; \ @@ -71,13 +71,13 @@ ({ \ int __atg2_result; \ if (sizeof (*mem) == 1) \ - __atg2_result = pre##_8_##post (mem, __VA_ARGS__); \ + __atg2_result = (int) pre##_8_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 2) \ - __atg2_result = pre##_16_##post (mem, __VA_ARGS__); \ + __atg2_result = (int) pre##_16_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 4) \ - __atg2_result = pre##_32_##post (mem, __VA_ARGS__); \ + __atg2_result = (int) pre##_32_##post (mem, __VA_ARGS__); \ else if (sizeof (*mem) == 8) \ - __atg2_result = pre##_64_##post (mem, __VA_ARGS__); \ + __atg2_result = (int) pre##_64_##post (mem, __VA_ARGS__); \ else \ abort (); \ __atg2_result; \ diff --git a/include/elf.h b/include/elf.h index c2efa9978..1e7c89615 100644 --- a/include/elf.h +++ b/include/elf.h @@ -3588,8 +3588,12 @@ typedef Elf32_Addr Elf32_Conflict; #define R_XTENSA_TLSDESC_FN 50 #define R_XTENSA_TLSDESC_ARG 51 #define R_XTENSA_TLS_TPOFF 53 +#define R_XTENSA_SYM32 63 +#define R_XTENSA_FUNCDESC 68 +#define R_XTENSA_FUNCDESC_VALUE 69 +#define R_XTENSA_TLSDESC 72 /* Keep this the last entry. */ -#define R_XTENSA_NUM 54 +#define R_XTENSA_NUM 77 /* C6X specific relocs */ #define R_C6000_NONE 0 diff --git a/include/features.h b/include/features.h index 11b34205f..1a4efb9db 100644 --- a/include/features.h +++ b/include/features.h @@ -140,6 +140,18 @@ # define __GNUC_PREREQ(maj, min) 0 #endif +/* Convenience macro to test the version of clang. + Use like this: + #if __CLANG_PREREQ(3,2) + ... code requiring clang 3.2 or later ... + #endif */ +#if defined __clang__ +# define __CLANG_PREREQ(maj, min) \ + ((__clang_major__ << 16) + __clang_minor__ >= ((maj) << 16) + (min)) +#else +# define __CLANG_PREREQ(maj, min) 0 +#endif + /* Whether to use feature set F. */ #define __GLIBC_USE(F) __GLIBC_USE_ ## F @@ -437,4 +449,8 @@ # include <libc-internal.h> #endif +#if defined(__UCLIBC_USE_TIME64__) || __TARGET_ARCH_BITS__ == 64 +#define __USE_TIME_BITS64 1 +#endif + #endif /* features.h */ diff --git a/include/fenv.h b/include/fenv.h index 9ba384756..4b532c573 100644 --- a/include/fenv.h +++ b/include/fenv.h @@ -23,6 +23,7 @@ #define _FENV_H 1 #include <features.h> +#include <stdbool.h> /* Get the architecture dependend definitions. The following definitions are expected to be done: @@ -130,6 +131,15 @@ extern int fedisableexcept (int __excepts) __THROW; extern int fegetexcept (void) __THROW; #endif +/* Rounding mode context. This allows functions to set/restore rounding mode + only when the desired rounding mode is different from the current rounding + mode. */ +struct rm_ctx +{ + fenv_t env; + bool updated_status; +}; + __END_DECLS #endif /* fenv.h */ diff --git a/include/internal/time64_helpers.h b/include/internal/time64_helpers.h index 2284aacd9..e2ed0f3bb 100644 --- a/include/internal/time64_helpers.h +++ b/include/internal/time64_helpers.h @@ -1,10 +1,15 @@ #ifndef _TIME64_HELPERS_H #define _TIME64_HELPERS_H +#include <linux/version.h> #include <bits/types.h> #include <time.h> #include <stddef.h> +#if defined(__UCLIBC_USE_TIME64__) && __TARGET_ARCH_BITS__ == 32 && LINUX_VERSION_CODE < KERNEL_VERSION(5,1,0) +#error 64bit time on 32bit targets is not supported on Linux < 5.1.0 +#endif + struct __ts64_struct { __S64_TYPE tv_sec; __S64_TYPE tv_nsec; diff --git a/include/libintl.h b/include/libintl.h index b7123a963..6d8b9f342 100644 --- a/include/libintl.h +++ b/include/libintl.h @@ -50,9 +50,6 @@ char *bindtextdomain(const char *domainname, const char *dirname); #endif -#include <stdio.h> -#define gettext_printf(args...) printf(args) - /* to supply LC_MESSAGES and other stuff GNU expects to be exported when including libintl.h */ #include <locale.h> diff --git a/include/net/ppp_defs.h b/include/net/ppp_defs.h index f8924c4f2..904d1933c 100644 --- a/include/net/ppp_defs.h +++ b/include/net/ppp_defs.h @@ -4,7 +4,7 @@ #define __need_time_t #include <time.h> -#include <asm/types.h> +#include <sys/types.h> #include <linux/ppp_defs.h> #endif /* net/ppp_defs.h */ diff --git a/include/netdb.h b/include/netdb.h index a85797956..26c999e59 100644 --- a/include/netdb.h +++ b/include/netdb.h @@ -689,7 +689,7 @@ extern const char *gai_strerror (int __ecode) __THROW; extern int getnameinfo (const struct sockaddr *__restrict __sa, socklen_t __salen, char *__restrict __host, socklen_t __hostlen, char *__restrict __serv, - socklen_t __servlen, unsigned int __flags); + socklen_t __servlen, int __flags); libc_hidden_proto(getnameinfo) #endif /* POSIX */ diff --git a/include/pty.h b/include/pty.h index f23a260ae..609ac2459 100644 --- a/include/pty.h +++ b/include/pty.h @@ -31,13 +31,15 @@ __BEGIN_DECLS attributes according to TERMP and WINP and return handles for both ends in AMASTER and ASLAVE. */ extern int openpty (int *__amaster, int *__aslave, char *__name, - struct termios *__termp, struct winsize *__winp) __THROW; + const struct termios *__termp, + const struct winsize *__winp) __THROW; libutil_hidden_proto(openpty) /* Create child process and establish the slave pseudo terminal as the child's controlling terminal. */ extern int forkpty (int *__amaster, char *__name, - struct termios *__termp, struct winsize *__winp) __THROW; + const struct termios *__termp, + const struct winsize *__winp) __THROW; __END_DECLS diff --git a/include/spawn.h b/include/spawn.h index 3de375b41..cf01639c1 100644 --- a/include/spawn.h +++ b/include/spawn.h @@ -103,6 +103,7 @@ int posix_spawnattr_init (posix_spawnattr_t *__attr) static inline int posix_spawnattr_destroy (posix_spawnattr_t *__attr) { + (void)__attr; return 0; } diff --git a/include/stdint.h b/include/stdint.h index 749f73697..5fedfb574 100644 --- a/include/stdint.h +++ b/include/stdint.h @@ -144,11 +144,19 @@ typedef unsigned long long int uintmax_t; # if __WORDSIZE == 64 +# ifndef __INT64_C # define __INT64_C(c) c ## L +# endif +# ifndef __UINT64_C # define __UINT64_C(c) c ## UL +# endif # else +# ifndef __INT64_C # define __INT64_C(c) c ## LL +# endif +# ifndef __UINT64_C # define __UINT64_C(c) c ## ULL +# endif # endif /* Limits of integral types. */ diff --git a/include/stdio.h b/include/stdio.h index 0915da909..a48fa9b78 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -110,7 +110,10 @@ typedef __STDIO_fpos64_t fpos64_t; #define SEEK_SET 0 /* Seek from beginning of file. */ #define SEEK_CUR 1 /* Seek from current position. */ #define SEEK_END 2 /* Seek from end of file. */ - +#ifdef __USE_GNU +# define SEEK_DATA 3 /* Seek to next data. */ +# define SEEK_HOLE 4 /* Seek to next hole. */ +#endif #if defined __USE_SVID || defined __USE_XOPEN /* Default path prefix for `mkstemp'. */ diff --git a/include/stdlib.h b/include/stdlib.h index 8b1375184..448c5e336 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -606,7 +606,7 @@ libc_hidden_proto(unsetenv) #ifdef __UCLIBC_DYNAMIC_ATEXIT__ # define __UCLIBC_MAX_ATEXIT INT_MAX #else -# define __UCLIBC_MAX_ATEXIT 20 +# define __UCLIBC_MAX_ATEXIT 32 #endif @@ -986,9 +986,13 @@ extern int getpt (void); extern int getloadavg (double __loadavg[], int __nelem) __THROW __nonnull ((1)); +/* reallocarray() only provided by the malloc-standard implementation */ +#if defined(__MALLOC_STANDARD__) extern void *reallocarray (void *__ptr, size_t __m, size_t __n); #endif +#endif + #ifdef _LIBC extern int __drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer) attribute_hidden; diff --git a/include/sys/cdefs.h b/include/sys/cdefs.h index 5c4daebcd..656548c52 100644 --- a/include/sys/cdefs.h +++ b/include/sys/cdefs.h @@ -58,9 +58,15 @@ # define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct # else # if defined __cplusplus && __GNUC_PREREQ (2,8) -# define __THROW throw () -# define __THROWNL throw () -# define __NTH(fct) __LEAF_ATTR fct throw () +/* Dynamic exception specification is deprecated since C++11, so + we only use it when compiling for an earlier standard. */ +# if __cplusplus < 201103UL +# define __THROW throw () +# else +# define __THROW noexcept +# endif +# define __THROWNL __THROW +# define __NTH(fct) __LEAF_ATTR fct __THROW # else # define __THROW # define __THROWNL @@ -314,7 +320,7 @@ inline semantics, unless -fgnu89-inline is used. For -std=gnu99, forcing gnu_inline attribute does not change behavior, but may silence spurious warnings (such as in GCC 4.2). */ -#if !defined __cplusplus || __GNUC_PREREQ (4,3) +#if !defined __cplusplus || __GNUC_PREREQ (4,3) || __CLANG_PREREQ(8,0) # if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ || defined __cplusplus # define __extern_inline extern __inline __attribute__ ((__gnu_inline__)) # if __GNUC_PREREQ (4,3) diff --git a/include/sys/mount.h b/include/sys/mount.h index c0e7b84f8..f9edbeba3 100644 --- a/include/sys/mount.h +++ b/include/sys/mount.h @@ -32,54 +32,79 @@ supported */ enum { +#undef MS_RDONLY MS_RDONLY = 1, /* Mount read-only. */ #define MS_RDONLY MS_RDONLY +#undef MS_NOSUID MS_NOSUID = 2, /* Ignore suid and sgid bits. */ #define MS_NOSUID MS_NOSUID +#undef MS_NODEV MS_NODEV = 4, /* Disallow access to device special files. */ #define MS_NODEV MS_NODEV +#undef MS_NOEXEC MS_NOEXEC = 8, /* Disallow program execution. */ #define MS_NOEXEC MS_NOEXEC +#undef MS_SYNCHRONOUS MS_SYNCHRONOUS = 16, /* Writes are synced at once. */ #define MS_SYNCHRONOUS MS_SYNCHRONOUS +#undef MS_REMOUNT MS_REMOUNT = 32, /* Alter flags of a mounted FS. */ #define MS_REMOUNT MS_REMOUNT +#undef MS_MANDLOCK MS_MANDLOCK = 64, /* Allow mandatory locks on an FS. */ #define MS_MANDLOCK MS_MANDLOCK +#undef MS_DIRSYNC MS_DIRSYNC = 128, /* Directory modifications are synchronous. */ #define MS_DIRSYNC MS_DIRSYNC +#undef MS_NOATIME MS_NOATIME = 1024, /* Do not update access times. */ #define MS_NOATIME MS_NOATIME +#undef MS_NODIRATIME MS_NODIRATIME = 2048, /* Do not update directory access times. */ #define MS_NODIRATIME MS_NODIRATIME +#undef MS_BIND MS_BIND = 4096, /* Bind directory at different place. */ #define MS_BIND MS_BIND +#undef MS_MOVE MS_MOVE = 8192, #define MS_MOVE MS_MOVE +#undef MS_REC MS_REC = 16384, #define MS_REC MS_REC +#undef MS_SILENT MS_SILENT = 32768, #define MS_SILENT MS_SILENT +#undef MS_POSIXACL MS_POSIXACL = 1 << 16, /* VFS does not apply the umask. */ #define MS_POSIXACL MS_POSIXACL +#undef MS_UNBINDABLE MS_UNBINDABLE = 1 << 17, /* Change to unbindable. */ #define MS_UNBINDABLE MS_UNBINDABLE +#undef MS_PRIVATE MS_PRIVATE = 1 << 18, /* Change to private. */ #define MS_PRIVATE MS_PRIVATE +#undef MS_SLAVE MS_SLAVE = 1 << 19, /* Change to slave. */ #define MS_SLAVE MS_SLAVE +#undef MS_SHARED MS_SHARED = 1 << 20, /* Change to shared. */ #define MS_SHARED MS_SHARED +#undef MS_RELATIME MS_RELATIME = 1 << 21, /* Update atime relative to mtime/ctime. */ #define MS_RELATIME MS_RELATIME +#undef MS_KERNMOUNT MS_KERNMOUNT = 1 << 22, /* This is a kern_mount call. */ #define MS_KERNMOUNT MS_KERNMOUNT +#undef MS_I_VERSION MS_I_VERSION = 1 << 23, /* Update inode I_version field. */ #define MS_I_VERSION MS_I_VERSION +#undef MS_STRICTATIME MS_STRICTATIME = 1 << 24, /* Always perform atime updates. */ #define MS_STRICTATIME MS_STRICTATIME +#undef MS_ACTIVE MS_ACTIVE = 1 << 30, #define MS_ACTIVE MS_ACTIVE +#undef MS_NOUSER MS_NOUSER = 1 << 31 #define MS_NOUSER MS_NOUSER }; diff --git a/include/sys/stat.h b/include/sys/stat.h index 99a6382a0..2dca6c552 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -371,7 +371,7 @@ extern int mkfifo (const char *__path, __mode_t __mode) extern int mkfifoat (int __fd, const char *__path, __mode_t __mode) __THROW __nonnull ((2)); #endif - + #ifdef __USE_ATFILE /* Set file access and modification times relative to directory file descriptor. */ @@ -386,7 +386,7 @@ libc_hidden_proto(utimensat) /* Set file access and modification times of the file associated with FD. */ extern int futimens (int __fd, const struct timespec __times[2]) __THROW; #endif - + /* on uClibc we have unversioned struct stat and mknod. * bits/stat.h is filled with wrong info, so we undo it here. */ #undef _STAT_VER diff --git a/include/sys/uio.h b/include/sys/uio.h index 330426fec..9e9708c0c 100644 --- a/include/sys/uio.h +++ b/include/sys/uio.h @@ -74,6 +74,25 @@ extern ssize_t pwritev (int __fd, const struct iovec *__iovec, int __count, __off64_t __offset) __wur; #endif /* Use misc. */ +#ifdef __USE_GNU +/* Read from another process' address space. */ +extern ssize_t process_vm_readv (pid_t __pid, const struct iovec *__lvec, + unsigned long int __liovcnt, + const struct iovec *__rvec, + unsigned long int __riovcnt, + unsigned long int __flags) + __THROW; + +/* Write to another process' address space. */ +extern ssize_t process_vm_writev (pid_t __pid, const struct iovec *__lvec, + unsigned long int __liovcnt, + const struct iovec *__rvec, + unsigned long int __riovcnt, + unsigned long int __flags) + __THROW; + +#endif + __END_DECLS #endif /* sys/uio.h */ diff --git a/include/ucontext.h b/include/ucontext.h index 4ce114ef1..76b4f375e 100644 --- a/include/ucontext.h +++ b/include/ucontext.h @@ -23,11 +23,11 @@ #include <features.h> -#ifdef __UCLIBC_HAS_CONTEXT_FUNCS__ - /* Get machine dependent definition of data structures. */ #include <sys/ucontext.h> +#ifdef __UCLIBC_HAS_CONTEXT_FUNCS__ + __BEGIN_DECLS /* Get user context and store it in variable pointed to by UCP. */ diff --git a/include/unistd.h b/include/unistd.h index 36cd5fcb5..e45266f14 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -316,6 +316,10 @@ libc_hidden_proto(faccessat) # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Seek from end of file. */ +# ifdef __USE_GNU +# define SEEK_DATA 3 /* Seek to next data. */ +# define SEEK_HOLE 4 /* Seek to next hole. */ +# endif #endif #if defined __USE_BSD && !defined L_SET @@ -1246,6 +1250,15 @@ extern void swab (const void *__restrict __from, void *__restrict __to, extern char *ctermid (char *__s) __THROW; #endif +/* OpenBSD-compatible access to random bytes. + May be a cancellation point here, unlike in glibc/musl. */ +#ifdef _DEFAULT_SOURCE +# ifndef __getentropy_defined +extern int getentropy(void *__buf, size_t __len) __nonnull ((1)) __wur; +# define __getentropy_defined +# endif +#endif + __END_DECLS diff --git a/ldso/include/dl-auxvt.h b/ldso/include/dl-auxvt.h new file mode 100644 index 000000000..29eda6eb3 --- /dev/null +++ b/ldso/include/dl-auxvt.h @@ -0,0 +1,9 @@ +#ifndef _DL_AUXVT_H +#define _DL_AUXVT_H + +#define AUX_MAX_AT_ID 40 +extern ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID]; /* Cache frequently accessed auxiliary vector entries */ +extern ElfW(auxv_t) *_dl_auxv_start; /* Start of the auxiliary vector */ + +#endif /* _DL_AUXVT_H */ + diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h index b40f58b10..c143b8d45 100644 --- a/ldso/include/dl-syscall.h +++ b/ldso/include/dl-syscall.h @@ -11,8 +11,13 @@ * been dynamicly linked in yet. */ #include "sys/syscall.h" extern int _dl_errno; + +#ifdef UCLIBC_LDSO #undef __set_errno #define __set_errno(X) {(_dl_errno) = (X);} +#endif + +#include <linux/version.h> /* Pull in the arch specific syscall implementation */ #include <dl-syscalls.h> @@ -136,7 +141,7 @@ static __always_inline int _dl_stat(const char *file_name, { return _dl_newfstatat(AT_FDCWD, file_name, buf, 0); } -#elif defined __NR_stat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__)) +#elif defined __NR_stat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__) || (LINUX_VERSION_CODE <= KERNEL_VERSION(5,1,0))) # define __NR__dl_stat __NR_stat static __always_inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf) @@ -163,7 +168,7 @@ static __always_inline int _dl_stat(const char *file_name, #if defined __NR_fstat64 && !defined __NR_fstat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__)) # define __NR__dl_fstat __NR_fstat64 static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf) -#elif defined __NR_fstat +#elif defined __NR_fstat && !defined __UCLIBC_USE_TIME64__ || defined(__sparc__) # define __NR__dl_fstat __NR_fstat static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf) #elif defined __NR_statx && defined __UCLIBC_HAVE_STATX__ diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h index 80d5d5dd5..061d8a536 100755 --- a/ldso/include/ldso.h +++ b/ldso/include/ldso.h @@ -191,13 +191,8 @@ extern void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE loa #endif -#define AUX_MAX_AT_ID 40 -extern ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID]; +#include <dl-auxvt.h> -void load_vdso( uint32_t sys_info_ehdr, char **envp ); - -#ifdef __VDSO_SUPPORT__ -extern void* _dl__vdso_gettimeofday; -#endif +void load_vdso(void *sys_info_ehdr, char **envp ); #endif /* _LDSO_H */ diff --git a/ldso/ldso/Makefile.in b/ldso/ldso/Makefile.in index 6e8a0c388..0f8ed140d 100644 --- a/ldso/ldso/Makefile.in +++ b/ldso/ldso/Makefile.in @@ -19,6 +19,11 @@ ifeq ($(TARGET_ARCH),arm) CFLAGS-rtld += -fno-unwind-tables -fno-asynchronous-unwind-tables endif +ifeq ($(TARGET_ARCH),bfin) +# for gcc 10.5.0 and above we need to use -ffreestanding +CFLAGS-rtld += -ffreestanding +endif + CFLAGS-rtld += -I$(top_srcdir)ldso/ldso/$(TARGET_ARCH) -I$(top_srcdir)ldso/include -I$(top_srcdir)ldso/ldso CFLAGS-rtld += -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" -DUCLIBC_LDSO=\"$(UCLIBC_LDSO)\" diff --git a/ldso/ldso/aarch64/dl-syscalls.h b/ldso/ldso/aarch64/dl-syscalls.h index f40c4fd31..7f3566d6b 100644 --- a/ldso/ldso/aarch64/dl-syscalls.h +++ b/ldso/ldso/aarch64/dl-syscalls.h @@ -1 +1,38 @@ -/* stub for arch-specific syscall issues */ +/* stub for arch-specific syscall issues/specific implementations */ +#ifndef _DL_SYSCALLS_H +#define _DL_SYSCALLS_H + +#ifdef __ARCH_VDSO_GETTIMEOFDAY_NAME +#undef __ARCH_VDSO_GETTIMEOFDAY_NAME +#endif + +#ifdef __ARCH_VDSO_CLOCK_GETTIME_NAME +#undef __ARCH_VDSO_CLOCK_GETTIME_NAME +#endif + +#define __ARCH_VDSO_GETTIMEOFDAY_NAME "__kernel_gettimeofday" +#define __ARCH_VDSO_CLOCK_GETTIME_NAME "__kernel_clock_gettime" + +#if defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) + +#include "../dl-vdso-calls.h" + +static int __attribute__ ((used)) __aarch64_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp); +static int __attribute__ ((used)) __aarch64_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + return __generic_vdso_clock_gettime(clock_id, tp); +} + +static int __attribute__ ((used)) __aarch64_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz); +static int __attribute__ ((used)) __aarch64_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz) +{ + return __generic_vdso_gettimeofday(tv, tz); +} + +#define ARCH_VDSO_GETTIMEOFDAY(tv, tz) __aarch64_vdso_gettimeofday(tv, tz) +#define ARCH_VDSO_CLOCK_GETTIME(clock_id, tp) __aarch64_vdso_clock_gettime(clock_id, tp) + +#endif /* defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) */ + +#endif /* _DL_SYSCALLS_H */ + diff --git a/ldso/ldso/aarch64/dl-sysdep.h b/ldso/ldso/aarch64/dl-sysdep.h index 6d9d2c1fb..3466920d9 100644 --- a/ldso/ldso/aarch64/dl-sysdep.h +++ b/ldso/ldso/aarch64/dl-sysdep.h @@ -54,28 +54,21 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); || (type) == R_AARCH64_TLSDESC) * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_AARCH64_COPY) * ELF_RTYPE_CLASS_COPY)) -/* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. */ -extern const ElfW(Addr) _GLOBAL_OFFSET_TABLE_[] attribute_hidden; -static __always_inline ElfW(Addr) __attribute__ ((unused)) -elf_machine_dynamic (void) -{ - return _GLOBAL_OFFSET_TABLE_[0]; -} - /* Return the run-time load address of the shared object. */ static __always_inline ElfW(Addr) __attribute__ ((unused)) elf_machine_load_address (void) { - /* To figure out the load address we use the definition that for any symbol: - dynamic_addr(symbol) = static_addr(symbol) + load_addr - - _DYNAMIC sysmbol is used here as its link-time address stored in - the special unrelocated first GOT entry. */ + extern const ElfW(Ehdr) __ehdr_start attribute_hidden; + return (ElfW(Addr)) &__ehdr_start; +} - extern ElfW(Dyn) _DYNAMIC[] attribute_hidden; - return (ElfW(Addr)) &_DYNAMIC - elf_machine_dynamic (); +/* Return the link-time address of _DYNAMIC. */ +static __always_inline ElfW(Addr) __attribute__ ((unused)) +elf_machine_dynamic (void) +{ + extern ElfW(Dyn) _DYNAMIC[] attribute_hidden; + return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address (); } static __always_inline void diff --git a/ldso/ldso/aarch64/elfinterp.c b/ldso/ldso/aarch64/elfinterp.c index 717a76980..d8530ecd1 100644 --- a/ldso/ldso/aarch64/elfinterp.c +++ b/ldso/ldso/aarch64/elfinterp.c @@ -227,17 +227,23 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, #else if (!TRY_STATIC_TLS ((struct link_map *) tls_tpnt)) { - td->arg = _dl_make_tlsdesc_dynamic((struct link_map *) tls_tpnt, symbol_addr); + td->arg = _dl_make_tlsdesc_dynamic((struct link_map *) tls_tpnt, symbol_addr + rpnt->r_addend); td->entry = _dl_tlsdesc_dynamic; } else #endif { - td->arg = (void*)(symbol_addr + tls_tpnt->l_tls_offset); + td->arg = (void*)(symbol_addr + tls_tpnt->l_tls_offset + rpnt->r_addend); td->entry = _dl_tlsdesc_return; } } break; + case R_AARCH64_TLS_DTPMOD: + *reloc_addr = tls_tpnt->l_tls_modid; + break; + case R_AARCH64_TLS_DTPREL: + *reloc_addr = symbol_addr + rpnt->r_addend; + break; #endif default: return -1; /*call _dl_exit(1) */ diff --git a/ldso/ldso/arm/dl-syscalls.h b/ldso/ldso/arm/dl-syscalls.h index f40c4fd31..5f6f7a883 100644 --- a/ldso/ldso/arm/dl-syscalls.h +++ b/ldso/ldso/arm/dl-syscalls.h @@ -1 +1,28 @@ -/* stub for arch-specific syscall issues */ +/* stub for arch-specific syscall issues/specific implementations */ + +#ifndef _DL_SYSCALLS_H +#define _DL_SYSCALLS_H + +#if defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) + +#include "../dl-vdso-calls.h" + +static int __attribute__ ((used)) __arm_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp); +static int __attribute__ ((used)) __arm_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + return __generic_vdso_clock_gettime(clock_id, tp); +} + +static int __attribute__ ((used)) __arm_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz); +static int __attribute__ ((used)) __arm_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz) +{ + return __generic_vdso_gettimeofday(tv, tz); +} + +#define ARCH_VDSO_GETTIMEOFDAY(tv, tz) __arm_vdso_gettimeofday(tv, tz) +#define ARCH_VDSO_CLOCK_GETTIME(clock_id, tp) __arm_vdso_clock_gettime(clock_id, tp) + +#endif /* defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) */ + +#endif /* _DL_SYSCALLS_H */ + diff --git a/ldso/ldso/arm/dl-sysdep.h b/ldso/ldso/arm/dl-sysdep.h index 0f783e1c4..93e36b694 100644 --- a/ldso/ldso/arm/dl-sysdep.h +++ b/ldso/ldso/arm/dl-sysdep.h @@ -96,43 +96,6 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); | (((type) == R_ARM_COPY) * ELF_RTYPE_CLASS_COPY)) #endif /* __FDPIC__ */ -/* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. We used to use the PIC register to do this - without a constant pool reference, but GCC 4.2 will use a pseudo-register - for the PIC base, so it may not be in r10. */ -static __always_inline Elf32_Addr __attribute__ ((unused)) -elf_machine_dynamic (void) -{ - Elf32_Addr dynamic; -#if !defined __thumb__ - __asm__ ("ldr %0, 2f\n" - "1: ldr %0, [pc, %0]\n" - "b 3f\n" - "2: .word _GLOBAL_OFFSET_TABLE_ - (1b+8)\n" - "3:" : "=r" (dynamic)); -#else - int tmp; - __asm__ (".align 2\n" - "bx pc\n" - "nop\n" - ".arm\n" - "ldr %0, 2f\n" - "1: ldr %0, [pc, %0]\n" - "b 3f\n" - "2: .word _GLOBAL_OFFSET_TABLE_ - (1b+8)\n" - "3:" - ".align 2\n" - "orr %1, pc, #1\n" - "bx %1\n" - ".force_thumb\n" - : "=r" (dynamic), "=&r" (tmp)); -#endif - - return dynamic; -} - -extern char __dl_start[] __asm__("_dl_start"); - #ifdef __FDPIC__ /* We must force strings used early in the bootstrap into the data segment. */ @@ -148,28 +111,16 @@ extern char __dl_start[] __asm__("_dl_start"); static __always_inline Elf32_Addr __attribute__ ((unused)) elf_machine_load_address (void) { -#if defined(__FDPIC__) - return 0; -#else - Elf32_Addr got_addr = (Elf32_Addr) &__dl_start; - Elf32_Addr pcrel_addr; -#if defined __OPTIMIZE__ && !defined __thumb__ - __asm__ ("adr %0, _dl_start" : "=r" (pcrel_addr)); -#else - /* A simple adr does not work in Thumb mode because the offset is - negative, and for debug builds may be too large. */ - int tmp; - __asm__ ("adr %1, 1f\n\t" - "ldr %0, [%1]\n\t" - "add %0, %0, %1\n\t" - "b 2f\n\t" - ".align 2\n\t" - "1: .word _dl_start - 1b\n\t" - "2:" - : "=r" (pcrel_addr), "=r" (tmp)); -#endif - return pcrel_addr - got_addr; -#endif + extern const Elf32_Ehdr __ehdr_start attribute_hidden; + return (Elf32_Addr) &__ehdr_start; +} + +/* Return the link-time address of _DYNAMIC. */ +static __always_inline Elf32_Addr __attribute__ ((unused)) +elf_machine_dynamic (void) +{ + extern Elf32_Dyn _DYNAMIC[] attribute_hidden; + return (Elf32_Addr) _DYNAMIC - elf_machine_load_address (); } static __always_inline void diff --git a/ldso/ldso/arm/elfinterp.c b/ldso/ldso/arm/elfinterp.c index 4c268356f..9c9a3e8ca 100644 --- a/ldso/ldso/arm/elfinterp.c +++ b/ldso/ldso/arm/elfinterp.c @@ -92,7 +92,7 @@ unsigned long _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_offet) *got_entry = funcval; #endif - return got_entry; + return (unsigned long)got_entry; } #else unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) @@ -362,7 +362,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, unsigned long reloc_value = *reloc_addr; if (symbol_addr) - reloc_value = (unsigned long) _dl_funcdesc_for(symbol_addr + reloc_value, sym_ref.tpnt->loadaddr.got_value); + reloc_value = (unsigned long) _dl_funcdesc_for((void *)(symbol_addr + reloc_value), sym_ref.tpnt->loadaddr.got_value); else /* Relocation against an undefined weak symbol: @@ -429,7 +429,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, { struct funcdesc_value *dst = (struct funcdesc_value *) reloc_addr; - dst->entry_point = DL_RELOC_ADDR(tpnt->loadaddr, dst->entry_point); + dst->entry_point = (void *)DL_RELOC_ADDR(tpnt->loadaddr, dst->entry_point); dst->got_value = tpnt->loadaddr.got_value; } break; diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 4f50d62b7..6656acb0f 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -1028,7 +1028,7 @@ int _dl_fixup(struct dyn_elf *rpnt, struct r_scope_elem *scope, int now_flag) return goof; } -#if !defined(__FDPIC__) && !defined(__DSBT__) +#if !defined(__FDPIC__) && !defined(__FRV_FDPIC__) && !defined(__DSBT__) /* Process DT_RELR relative relocations */ DL_RELOCATE_RELR(tpnt); #endif diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c index 5b992a3a2..ec6b72a39 100644 --- a/ldso/ldso/dl-startup.c +++ b/ldso/ldso/dl-startup.c @@ -100,6 +100,7 @@ extern ElfW(Addr) _begin[] attribute_hidden; ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID]; +ElfW(auxv_t) *_dl_auxv_start; #ifdef LDSO_NEED_DPNT ElfW(Dyn) *_dl_saved_dpnt = 0; @@ -131,6 +132,7 @@ DL_START(unsigned long args) struct elf_resolve tpnt_tmp; struct elf_resolve *tpnt = &tpnt_tmp; ElfW(auxv_t) _dl_auxvt_tmp[AUX_MAX_AT_ID]; + ElfW(auxv_t) *_dl_auxv_start_tmp; ElfW(Dyn) *dpnt; uint32_t *p32; @@ -166,6 +168,7 @@ DL_START(unsigned long args) /* The junk on the stack immediately following the environment is * the Auxiliary Vector Table. Read out the elements of the auxvt, * sort and store them in auxvt for later use. */ + _dl_auxv_start_tmp = (ElfW(auxv_t) *)aux_dat; while (*aux_dat) { ElfW(auxv_t) *auxv_entry = (ElfW(auxv_t) *) aux_dat; @@ -264,7 +267,7 @@ DL_START(unsigned long args) that once we are done, we have considerably more flexibility. */ SEND_EARLY_STDERR_DEBUG("About to do library loader relocations\n"); -#if !defined(__FDPIC__) && !defined(__DSBT__) +#if !defined(__FDPIC__) && !defined(__FRV_FDPIC__) && !defined(__DSBT__) /* Process DT_RELR relative relocations */ DL_RELOCATE_RELR(tpnt); #endif @@ -367,13 +370,14 @@ DL_START(unsigned long args) * now the globals work. so copy the aux vector */ _dl_memcpy( _dl_auxvt, _dl_auxvt_tmp, sizeof( ElfW(auxv_t) ) * AUX_MAX_AT_ID ); + _dl_auxv_start = _dl_auxv_start_tmp; _dl_elf_main = (int (*)(int, char **, char **)) _dl_get_ready_to_run(tpnt, load_addr, envp, argv DL_GET_READY_TO_RUN_EXTRA_ARGS); - load_vdso(_dl_auxvt[AT_SYSINFO_EHDR].a_un.a_val, envp); + load_vdso((void *)_dl_auxvt[AT_SYSINFO_EHDR].a_un.a_val, envp); /* Transfer control to the application. */ SEND_STDERR_DEBUG("transfering control to application @ "); diff --git a/ldso/ldso/dl-vdso-calls.h b/ldso/ldso/dl-vdso-calls.h new file mode 100644 index 000000000..c72f2dadf --- /dev/null +++ b/ldso/ldso/dl-vdso-calls.h @@ -0,0 +1,68 @@ +#ifndef _DL_VDSO_CALLS_H +#define _DL_VDSO_CALLS_H + +#include <sys/time.h> +#include <sys/syscall.h> +#include <errno.h> +#include <time.h> + +void __attribute__((weak)) *_get__dl__vdso_clock_gettime(void); +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +void __attribute__((weak)) *_get__dl__vdso_clock_gettime64(void); +typedef int (*clock_gettime_func)(clockid_t clock_id, struct __ts64_struct *tp); +#else +typedef int (*clock_gettime_func)(clockid_t clock_id, struct timespec *tp); +#endif + +extern int __libc_clock_gettime(clockid_t clock_id, struct timespec *tp); + +static int __attribute__ ((used)) __generic_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp); +static int __attribute__ ((used)) __generic_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + void *impl = NULL; +#if defined(__UCLIBC_USE_TIME64__) + if (&_get__dl__vdso_clock_gettime64 && (impl = _get__dl__vdso_clock_gettime64())) { + struct __ts64_struct __ts64; + int __ret = ((clock_gettime_func)impl)(clock_id, &__ts64); + if (__ret != 0) { + __set_errno(-__ret); + return -1; + } + + if (tp) { + tp->tv_sec = __ts64.tv_sec; + tp->tv_nsec = __ts64.tv_nsec; + } + return 0; + } + + /* fallback to syscall */ + return __libc_clock_gettime(clock_id, tp); +#else + if (&_get__dl__vdso_clock_gettime && (impl = _get__dl__vdso_clock_gettime())) { + int __ret = ((clock_gettime_func)impl)(clock_id, tp); + if (__ret != 0) { + __set_errno(-__ret); + return -1; + } + + return 0; + } + + /* fallback to syscall */ + return __libc_clock_gettime(clock_id, tp); +#endif +} + +static int __attribute__ ((used)) __generic_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz) +{ + struct timespec ts; + int __res = __generic_vdso_clock_gettime(CLOCK_REALTIME, &ts); + tv->tv_sec = ts.tv_sec; + tv->tv_usec = (suseconds_t)ts.tv_nsec / 1000; + + return __res; +} + +#endif /* _DL_VDSO_CALLS_H */
\ No newline at end of file diff --git a/ldso/ldso/dl-vdso.c b/ldso/ldso/dl-vdso.c index c8d724cd0..01309011d 100755 --- a/ldso/ldso/dl-vdso.c +++ b/ldso/ldso/dl-vdso.c @@ -1,12 +1,16 @@ #include <elf.h> -//#include <stdio.h> #include <string.h> - #include "sys/auxv.h" -//#include <linux/time.h> -//#include <time.h> +#define __ARCH_VDSO_GETTIMEOFDAY_NAME "__vdso_gettimeofday" +#define __ARCH_VDSO_CLOCK_GETTIME_NAME "__vdso_clock_gettime" + +#if defined(__UCLIBC_USE_TIME64__) +#define __ARCH_VDSO_CLOCK_GETTIME64_NAME "__vdso_clock_gettime64" +#endif + +/* Maybe override default vDSO functions names by arch-specific */ #include "ldso.h" #include "generated/autoconf.h" @@ -24,31 +28,44 @@ #ifndef __VDSO_SUPPORT__ - void load_vdso( uint32_t sys_info_ehdr, char **envp ){ +void load_vdso( void *sys_info_ehdr attribute_unused, + char **envp attribute_unused ){ #ifdef __SUPPORT_LD_DEBUG__ - if ( _dl_debug_vdso != 0 ){ - _dl_dprintf(2,"_dl_vdso support not enabled\n" ); - } - -#endif + if ( _dl_debug_vdso != 0 ){ + _dl_dprintf(2,"_dl_vdso support not enabled\n" ); } +#endif +} #else +void *_dl__vdso_gettimeofday = 0; +void *_dl__vdso_clock_gettime = 0; +#if defined(__UCLIBC_USE_TIME64__) +void *_dl__vdso_clock_gettime64 = 0; +#endif - - - -//typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz); -void* _dl__vdso_gettimeofday = 0; - - -//typedef long (*clock_gettime_t)(int clk_id, struct timespec *tp); -void* _dl__vdso_clock_gettime = 0; +void *_get__dl__vdso_clock_gettime(void); +void *_get__dl__vdso_clock_gettime(void) +{ + return _dl__vdso_clock_gettime; +} +#if defined(__UCLIBC_USE_TIME64__) +void *_get__dl__vdso_clock_gettime64(void); +void *_get__dl__vdso_clock_gettime64(void) +{ + return _dl__vdso_clock_gettime64; +} +#endif +void *_get__dl__vdso_gettimeofday(void); +void *_get__dl__vdso_gettimeofday(void) +{ + return _dl__vdso_gettimeofday; +} -typedef struct{ +typedef struct { void* base_addr; @@ -75,7 +92,7 @@ typedef struct{ char* vers_strings[10]; -}elf_infos; +} elf_infos; /* * the raise() dummy function is needed because of divisons in this code @@ -111,13 +128,10 @@ static ELF(Shdr) *vdso_get_sec_header( elf_infos* elf, int index ){ } - -void load_vdso( uint32_t sys_info_ehdr, char **envp ){ +void load_vdso(void *sys_info_ehdr, char **envp ){ elf_infos vdso_infos; - - - + if ( sys_info_ehdr == 0 ){ #ifdef __SUPPORT_LD_DEBUG__ if ( _dl_debug_vdso != 0 ){ @@ -137,22 +151,16 @@ void load_vdso( uint32_t sys_info_ehdr, char **envp ){ #endif return; } - - + _dl_memset( &vdso_infos, 0 , sizeof( elf_infos ) ); - - + vdso_infos.base_addr = (void*)sys_info_ehdr; vdso_infos.hdr = (ELF(Ehdr)*)vdso_infos.base_addr; - - //printf("base : %p\n",vdso_infos.base_addr); - + if ( 0 != vdso_check_elf_header( &vdso_infos ) ){ return; } - - - + ELF(Shdr) *sec_header = vdso_get_sec_header( &vdso_infos, vdso_infos.hdr->e_shstrndx); vdso_infos.section_header_strtab = ( vdso_infos.base_addr + sec_header->sh_offset ); @@ -307,10 +315,7 @@ void load_vdso( uint32_t sys_info_ehdr, char **envp ){ if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC) continue; - - char* name = vdso_infos.dynstr_table + sym->st_name; - char* vers = vdso_infos.vers_strings[ vdso_infos.versym_table[i] ]; void* func_addr = (void*)( vdso_infos.base_addr + sym->st_value ); // the function name is patched to zero if the kernel has no timer which is @@ -324,10 +329,7 @@ void load_vdso( uint32_t sys_info_ehdr, char **envp ){ continue; } - //printf(" %s@@%s\n", name , vers ); - - //print_sym( sym ); - if ( 0 == _dl_strcmp( name, "__vdso_gettimeofday" ) ){ + if ( 0 == _dl_strcmp( name, __ARCH_VDSO_GETTIMEOFDAY_NAME ) ){ _dl__vdso_gettimeofday = func_addr; #ifdef __SUPPORT_LD_DEBUG__ if ( _dl_debug_vdso != 0 ){ @@ -336,8 +338,7 @@ void load_vdso( uint32_t sys_info_ehdr, char **envp ){ #endif continue; } - - if ( 0 == _dl_strcmp( name, "__vdso_clock_gettime" ) ){ + if ( 0 == _dl_strcmp( name, __ARCH_VDSO_CLOCK_GETTIME_NAME ) ){ _dl__vdso_clock_gettime = func_addr; #ifdef __SUPPORT_LD_DEBUG__ if ( _dl_debug_vdso != 0 ){ @@ -346,17 +347,26 @@ void load_vdso( uint32_t sys_info_ehdr, char **envp ){ #endif continue; } + +#if defined(__UCLIBC_USE_TIME64__) + if ( 0 == _dl_strcmp( name, __ARCH_VDSO_CLOCK_GETTIME64_NAME ) ){ + _dl__vdso_clock_gettime64 = func_addr; +#ifdef __SUPPORT_LD_DEBUG__ + if ( _dl_debug_vdso != 0 ){ + _dl_dprintf(2," %s at address %p\n", name, func_addr ); + } +#endif + continue; + } +#endif /* defined(__UCLIBC_USE_TIME64__) */ #ifdef __SUPPORT_LD_DEBUG__ if ( _dl_debug_vdso != 0 ){ _dl_dprintf(2," <%s> not handled\n", name ); } #endif - - - } - + } } #endif // __VDSO_SUPPORT__ diff --git a/ldso/ldso/fdpic/dl-inlines.h b/ldso/ldso/fdpic/dl-inlines.h index 89e7a9a68..6a31ef3e6 100644 --- a/ldso/ldso/fdpic/dl-inlines.h +++ b/ldso/ldso/fdpic/dl-inlines.h @@ -102,7 +102,7 @@ __dl_update_loadaddr_hdr(struct elf32_fdpic_loadaddr loadaddr, void *addr, #if defined (__SUPPORT_LD_DEBUG__) if (_dl_debug) - _dl_dprintf(_dl_debug_file, "%i: changed mapping %x at %x (old %x), size %x\n", + _dl_dprintf(_dl_debug_file, "%i: changed mapping %x at %x (old %p), size %x\n", loadaddr.map->nsegs - 1, segdata->p_vaddr, segdata->addr, oldaddr, segdata->p_memsz); #endif @@ -177,7 +177,7 @@ _dl_funcdesc_for (void *entry_point, void *got_value) tpnt->funcdesc_ht = ht; } - entry = htab_find_slot(ht, entry_point, 1, hash_pointer, eq_pointer); + entry = (struct funcdesc_value **)htab_find_slot(ht, entry_point, 1, hash_pointer, eq_pointer); if (entry == NULL) _dl_exit(1); diff --git a/ldso/ldso/fdpic/dl-sysdep.h b/ldso/ldso/fdpic/dl-sysdep.h index 6ab303b37..81694dc76 100644 --- a/ldso/ldso/fdpic/dl-sysdep.h +++ b/ldso/ldso/fdpic/dl-sysdep.h @@ -108,7 +108,7 @@ struct funcdesc_ht; && ELF32_ST_TYPE((SYM)->st_info) == STT_FUNC \ ? _dl_funcdesc_for ((void *)DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value), \ (TPNT)->loadaddr.got_value) \ - : DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value)) + : (void*)DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value)) #define DL_GET_READY_TO_RUN_EXTRA_PARMS \ , struct elf32_fdpic_loadmap *dl_boot_progmap, Elf32_Addr dl_boot_got_pointer diff --git a/ldso/ldso/i386/dl-syscalls.h b/ldso/ldso/i386/dl-syscalls.h index f40c4fd31..8f144ee28 100644 --- a/ldso/ldso/i386/dl-syscalls.h +++ b/ldso/ldso/i386/dl-syscalls.h @@ -1 +1,29 @@ +/* stub for arch-specific syscall issues/specific implementations */ + +#ifndef _DL_SYSCALLS_H +#define _DL_SYSCALLS_H + +#if defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) + +#include "../dl-vdso-calls.h" + +static int __attribute__ ((used)) __x86_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp); +static int __attribute__ ((used)) __x86_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + return __generic_vdso_clock_gettime(clock_id, tp); +} + +static int __attribute__ ((used)) __x86_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz); +static int __attribute__ ((used)) __x86_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz) +{ + return __generic_vdso_gettimeofday(tv, tz); +} + +#define ARCH_VDSO_GETTIMEOFDAY(tv, tz) __x86_vdso_gettimeofday(tv, tz) +#define ARCH_VDSO_CLOCK_GETTIME(clock_id, tp) __x86_vdso_clock_gettime(clock_id, tp) + +#endif /* defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) */ + +#endif /* _DL_SYSCALLS_H */ + /* stub for arch-specific syscall issues */ diff --git a/ldso/ldso/i386/dl-sysdep.h b/ldso/ldso/i386/dl-sysdep.h index b95328df4..8fc80a145 100644 --- a/ldso/ldso/i386/dl-sysdep.h +++ b/ldso/ldso/i386/dl-sysdep.h @@ -35,28 +35,21 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_ent || (type) == R_386_TLS_TPOFF) * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_386_COPY) * ELF_RTYPE_CLASS_COPY)) -/* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT, a special entry that is never relocated. */ -extern const Elf32_Addr _GLOBAL_OFFSET_TABLE_[] attribute_hidden; -static __always_inline Elf32_Addr __attribute__ ((unused, const)) -elf_machine_dynamic (void) -{ - /* This produces a GOTOFF reloc that resolves to zero at link time, so in - fact just loads from the GOT register directly. By doing it without - an asm we can let the compiler choose any register. */ - return _GLOBAL_OFFSET_TABLE_[0]; -} - -extern Elf32_Dyn bygotoff[] __asm__ ("_DYNAMIC") attribute_hidden; /* Return the run-time load address of the shared object. */ static __always_inline Elf32_Addr attribute_unused elf_machine_load_address (void) { - /* Compute the difference between the runtime address of _DYNAMIC as seen - by a GOTOFF reference, and the link-time address found in the special - unrelocated first GOT entry. */ - return (Elf32_Addr) &bygotoff - elf_machine_dynamic (); + extern const Elf32_Ehdr __ehdr_start attribute_hidden; + return (Elf32_Addr) &__ehdr_start; +} + +/* Return the link-time address of _DYNAMIC. */ +static __always_inline Elf32_Addr __attribute__ ((unused, const)) +elf_machine_dynamic (void) +{ + extern Elf32_Dyn _DYNAMIC[] attribute_hidden; + return (Elf32_Addr) _DYNAMIC - elf_machine_load_address (); } static __always_inline void diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index 435bd43bc..e866d6418 100755 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -682,7 +682,7 @@ of this helper program; chances are you did not intend to run this program.\n\ */ /* Now cover the application program. */ if (app_tpnt->dynamic_info[DT_TEXTREL]) { - int j; + unsigned int j; ElfW(Phdr) *ppnt_outer = ppnt; _dl_debug_early("calling mprotect on the application program\n"); ppnt = (ElfW(Phdr) *) _dl_auxvt[AT_PHDR].a_un.a_val; diff --git a/ldso/ldso/m68k/elfinterp.c b/ldso/ldso/m68k/elfinterp.c index 25ea23067..e7fa117da 100644 --- a/ldso/ldso/m68k/elfinterp.c +++ b/ldso/ldso/m68k/elfinterp.c @@ -193,7 +193,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, #endif #if defined (__SUPPORT_LD_DEBUG__) - old_val = *reloc_addr; + old_val = reloc_addr ? *reloc_addr : 0; #endif switch (reloc_type) { @@ -292,7 +292,7 @@ _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, reloc_type = ELF_R_TYPE(rpnt->r_info); #if defined (__SUPPORT_LD_DEBUG__) - old_val = *reloc_addr; + old_val = reloc_addr ? *reloc_addr : 0; #endif switch (reloc_type) { diff --git a/ldso/ldso/mips/dl-syscalls.h b/ldso/ldso/mips/dl-syscalls.h index f40c4fd31..d8407f17c 100644 --- a/ldso/ldso/mips/dl-syscalls.h +++ b/ldso/ldso/mips/dl-syscalls.h @@ -1 +1,28 @@ -/* stub for arch-specific syscall issues */ +/* stub for arch-specific syscall issues/specific implementations */ + +#ifndef _DL_SYSCALLS_H +#define _DL_SYSCALLS_H + +#if defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) + +#include "../dl-vdso-calls.h" + +static int __attribute__ ((used)) __mips_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp); +static int __attribute__ ((used)) __mips_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + return __generic_vdso_clock_gettime(clock_id, tp); +} + +static int __attribute__ ((used)) __mips_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz); +static int __attribute__ ((used)) __mips_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz) +{ + return __generic_vdso_gettimeofday(tv, tz); +} + +#define ARCH_VDSO_GETTIMEOFDAY(tv, tz) __mips_vdso_gettimeofday(tv, tz) +#define ARCH_VDSO_CLOCK_GETTIME(clock_id, tp) __mips_vdso_clock_gettime(clock_id, tp) + +#endif /* defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) */ + +#endif /* _DL_SYSCALLS_H */ + diff --git a/ldso/ldso/riscv32/dl-sysdep.h b/ldso/ldso/riscv32/dl-sysdep.h index e0a59fddd..02296b148 100644 --- a/ldso/ldso/riscv32/dl-sysdep.h +++ b/ldso/ldso/riscv32/dl-sysdep.h @@ -59,22 +59,20 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); | (ELF_RTYPE_CLASS_COPY * ((type) == R_RISCV_COPY))) -/* Return the link-time address of _DYNAMIC. */ -static inline ElfW(Addr) -elf_machine_dynamic (void) -{ - extern ElfW(Addr) _GLOBAL_OFFSET_TABLE_ __attribute__ ((visibility ("hidden"))); - return _GLOBAL_OFFSET_TABLE_; -} - - /* Return the run-time load address of the shared object. */ static __always_inline ElfW(Addr) __attribute__ ((unused)) elf_machine_load_address (void) { - ElfW(Addr) load_addr; - __asm__ ("lla %0, _DYNAMIC" : "=r" (load_addr)); - return load_addr - elf_machine_dynamic (); + extern const ElfW(Ehdr) __ehdr_start attribute_hidden; + return (ElfW(Addr)) &__ehdr_start; +} + +/* Return the link-time address of _DYNAMIC. */ +static inline ElfW(Addr) +elf_machine_dynamic (void) +{ + extern ElfW(Dyn) _DYNAMIC[] attribute_hidden; + return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address (); } static __always_inline void diff --git a/ldso/ldso/x86_64/dl-syscalls.h b/ldso/ldso/x86_64/dl-syscalls.h index f40c4fd31..3f953aa83 100644 --- a/ldso/ldso/x86_64/dl-syscalls.h +++ b/ldso/ldso/x86_64/dl-syscalls.h @@ -1 +1,28 @@ -/* stub for arch-specific syscall issues */ +/* stub for arch-specific syscall issues/specific implementations */ + +#ifndef _DL_SYSCALLS_H +#define _DL_SYSCALLS_H + +#if defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) + +#include "../dl-vdso-calls.h" + +static int __attribute__ ((used)) __x86_64_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp); +static int __attribute__ ((used)) __x86_64_vdso_clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + return __generic_vdso_clock_gettime(clock_id, tp); +} + +static int __attribute__ ((used)) __x86_64_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz); +static int __attribute__ ((used)) __x86_64_vdso_gettimeofday(struct timeval *tv, __timezone_ptr_t tz) +{ + return __generic_vdso_gettimeofday(tv, tz); +} + +#define ARCH_VDSO_GETTIMEOFDAY(tv, tz) __x86_64_vdso_gettimeofday(tv, tz) +#define ARCH_VDSO_CLOCK_GETTIME(clock_id, tp) __x86_64_vdso_clock_gettime(clock_id, tp) + +#endif /* defined(__VDSO_SUPPORT__) && !defined(UCLIBC_LDSO) */ + +#endif /* _DL_SYSCALLS_H */ + diff --git a/ldso/ldso/x86_64/dl-sysdep.h b/ldso/ldso/x86_64/dl-sysdep.h index ccf9a8851..58447a951 100644 --- a/ldso/ldso/x86_64/dl-sysdep.h +++ b/ldso/ldso/x86_64/dl-sysdep.h @@ -52,48 +52,21 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_ent * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_X86_64_COPY) * ELF_RTYPE_CLASS_COPY)) -/* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. This must be inlined in a function which - uses global data. */ -static __always_inline Elf64_Addr __attribute__ ((unused)) -elf_machine_dynamic (void) -{ - Elf64_Addr addr; - - /* This works because we have our GOT address available in the small PIC - model. */ - addr = (Elf64_Addr) &_DYNAMIC; - - return addr; -} - /* Return the run-time load address of the shared object. */ static __always_inline Elf64_Addr __attribute__ ((unused)) elf_machine_load_address (void) { - register Elf64_Addr addr, tmp; - - /* The easy way is just the same as on x86: - leaq _dl_start, %0 - leaq _dl_start(%%rip), %1 - subq %0, %1 - but this does not work with binutils since we then have - a R_X86_64_32S relocation in a shared lib. - - Instead we store the address of _dl_start in the data section - and compare it with the current value that we can get via - an RIP relative addressing mode. */ - - __asm__ ("movq 1f(%%rip), %1\n" - "0:\tleaq _dl_start(%%rip), %0\n\t" - "subq %1, %0\n\t" - ".section\t.data\n" - "1:\t.quad _dl_start\n\t" - ".previous\n\t" - : "=r" (addr), "=r" (tmp) : : "cc"); + extern const Elf64_Ehdr __ehdr_start attribute_hidden; + return (Elf64_Addr) &__ehdr_start; +} - return addr; +/* Return the link-time address of _DYNAMIC. */ +static __always_inline Elf64_Addr __attribute__ ((unused)) +elf_machine_dynamic (void) +{ + extern Elf64_Dyn _DYNAMIC[] attribute_hidden; + return (Elf64_Addr) _DYNAMIC - elf_machine_load_address (); } static __always_inline void diff --git a/ldso/ldso/xtensa/dl-inlines.h b/ldso/ldso/xtensa/dl-inlines.h new file mode 100644 index 000000000..8fdf6eb48 --- /dev/null +++ b/ldso/ldso/xtensa/dl-inlines.h @@ -0,0 +1 @@ +#include "../fdpic/dl-inlines.h" diff --git a/ldso/ldso/xtensa/dl-startup.h b/ldso/ldso/xtensa/dl-startup.h index c9350c0f2..2a453752a 100644 --- a/ldso/ldso/xtensa/dl-startup.h +++ b/ldso/ldso/xtensa/dl-startup.h @@ -7,6 +7,68 @@ * Parts taken from glibc/sysdeps/xtensa/dl-machine.h. */ +#if defined(__FDPIC__) +__asm__ ( + " .text\n" + " .align 4\n" + " .literal_position\n" + " .global _start\n" + " .type _start, @function\n" + " .hidden _start\n" + "_start:\n" + " .begin no-transform\n" + " _call0 1f\n" + "2:\n" + " .end no-transform\n" + " .align 4\n" + "1:\n" +#if defined(__XTENSA_CALL0_ABI__) + " movi a15, 2b\n" + " sub a15, a0, a15\n" + + /* Save FDPIC pointers in callee-saved registers */ + " mov a12, a4\n" + " mov a13, a5\n" + " mov a14, a6\n" + + /* Call __self_reloc */ + " mov a2, a5\n" + " movi a3, __ROFIXUP_LIST__\n" + " add a3, a3, a15\n" + " movi a4, __ROFIXUP_END__\n" + " add a4, a4, a15\n" + " movi a0, __self_reloc\n" + " add a0, a0, a15\n" + " callx0 a0\n" + + /* call _dl_start */ + " mov a3, a12\n" + " mov a4, a13\n" + " mov a5, a14\n" + " mov a7, sp\n" + " addi sp, sp, -16\n" + " mov a6, sp\n" + " mov a11, a2\n" + /* a13, interpreter map is no longer needed, save interpreter GOT there */ + " mov a13, a2\n" + " movi a0, _dl_start\n" + " add a0, a0, a15\n" + " callx0 a0\n" + + /* call main */ + " l32i a0, sp, 0\n" + " l32i a11, sp, 4\n" + " addi sp, sp, 16\n" + " mov a4, a12\n" + " movi a5, _dl_fini@GOTOFFFUNCDESC\n" + " add a5, a5, a13\n" + " mov a6, a14\n" + " jx a0\n" +#else +#error Unsupported Xtensa ABI +#endif + ); +#else /* __FDPIC__ */ #ifndef L_rcrt1 __asm__ ( " .text\n" @@ -83,6 +145,7 @@ __asm__ ( " bnez a6, 3b\n" " j .Lfixup_stack_ret"); #endif +#endif /* __FDPIC__ */ /* Get a pointer to the argv value. */ #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS) + 1) @@ -90,7 +153,7 @@ __asm__ ( /* Function calls are not safe until the GOT relocations have been done. */ #define NO_FUNCS_BEFORE_BOOTSTRAP -#if defined(__ARCH_USE_MMU__) +#if defined(__ARCH_USE_MMU__) && !defined(__FDPIC__) #define PERFORM_BOOTSTRAP_GOT(tpnt) \ do { \ xtensa_got_location *got_loc; \ @@ -128,3 +191,29 @@ do { \ } \ } while (0) #endif + +#ifdef __FDPIC__ +#undef DL_START +#define DL_START(X) \ +static void __attribute__ ((used)) \ +_dl_start (Elf32_Addr dl_boot_got_pointer, \ + struct elf32_fdpic_loadmap *dl_boot_progmap, \ + struct elf32_fdpic_loadmap *dl_boot_ldsomap, \ + Elf32_Dyn *dl_boot_ldso_dyn_pointer, \ + struct funcdesc_value *dl_main_funcdesc, \ + X) + +/* + * Transfer control to the user's application, once the dynamic loader + * is done. We return the address of the function's entry point to + * _dl_boot, see boot1_arch.h. + */ +#define START() do { \ + struct elf_resolve *exec_mod = _dl_loaded_modules; \ + dl_main_funcdesc->entry_point = _dl_elf_main; \ + while (exec_mod->libtype != elf_executable) \ + exec_mod = exec_mod->next; \ + dl_main_funcdesc->got_value = exec_mod->loadaddr.got_value; \ + return; \ +} while (0) +#endif /* __FDPIC__ */ diff --git a/ldso/ldso/xtensa/dl-sysdep.h b/ldso/ldso/xtensa/dl-sysdep.h index 6b908989a..5aa3e177f 100644 --- a/ldso/ldso/xtensa/dl-sysdep.h +++ b/ldso/ldso/xtensa/dl-sysdep.h @@ -26,6 +26,7 @@ in l_info array. */ #define DT_XTENSA(x) (DT_XTENSA_##x - DT_LOPROC + DT_NUM + OS_NUM) +#ifndef __FDPIC__ typedef struct xtensa_got_location_struct { Elf32_Off offset; Elf32_Word length; @@ -86,6 +87,7 @@ typedef struct xtensa_got_location_struct { else if (dpnt->d_tag == DT_XTENSA_GOT_LOC_SZ) \ dynamic[DT_XTENSA (GOT_LOC_SZ)] = dpnt->d_un.d_val; \ } while (0) +#endif /* Here we define the magic numbers that this dynamic loader should accept. */ #define MAGIC1 EM_XTENSA @@ -115,10 +117,41 @@ elf_machine_dynamic (void) return (Elf32_Addr) &_DYNAMIC; } +#ifdef __FDPIC__ + +#define DL_CHECK_LIB_TYPE(epnt, piclib, _dl_progname, libname) \ +do \ +{ \ + (piclib) = 2; \ +} \ +while (0) + +/* We must force strings used early in the bootstrap into the data + segment. */ +#undef SEND_EARLY_STDERR +#define SEND_EARLY_STDERR(S) \ + do { /* FIXME: implement */; } while (0) + +#undef INIT_GOT +#include "../fdpic/dl-sysdep.h" +#undef INIT_GOT +#define INIT_GOT(GOT_BASE,MODULE) \ +{ \ + (MODULE)->loadaddr.got_value = (GOT_BASE); \ + GOT_BASE[0] = ((unsigned long *)&_dl_linux_resolve)[0]; \ + GOT_BASE[1] = ((unsigned long *)&_dl_linux_resolve)[1]; \ + GOT_BASE[2] = (unsigned long) MODULE; \ +} + +#endif /* __FDPIC__ */ + /* Return the run-time load address of the shared object. */ static __always_inline Elf32_Addr elf_machine_load_address (void) { +#ifdef __FDPIC__ + return 0; +#else Elf32_Addr addr, tmp; /* At this point, the runtime linker is being bootstrapped and the GOT @@ -135,17 +168,48 @@ elf_machine_load_address (void) : "=a" (addr), "=a" (tmp)); return addr - 3; +#endif } +#ifdef __FDPIC__ + +/* Need bootstrap relocations */ +#define ARCH_NEEDS_BOOTSTRAP_RELOCS + +#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ + switch (ELF_R_TYPE((RELP)->r_info)){ \ + case R_XTENSA_SYM32: \ + *(REL) = (SYMBOL) + (RELP)->r_addend; \ + break; \ + case R_XTENSA_RELATIVE: \ + case R_XTENSA_NONE: \ + default: \ + break; \ + } + static __always_inline void -elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, +elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr, Elf32_Word relative_count) { Elf32_Rela *rpnt = (Elf32_Rela *) rel_addr; while (relative_count--) { + Elf32_Addr *const reloc_addr = (Elf32_Addr *) DL_RELOC_ADDR(load_off, rpnt->r_offset); + *reloc_addr = DL_RELOC_ADDR(load_off, *reloc_addr); + rpnt++; + } +} +#else +static __always_inline void +elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) +{ + Elf32_Rela *rpnt = (Elf32_Rela *) rel_addr; + while (relative_count--) + { Elf32_Addr *const reloc_addr = (Elf32_Addr *) (load_off + rpnt->r_offset); *reloc_addr += load_off + rpnt->r_addend; rpnt++; } } +#endif diff --git a/ldso/ldso/xtensa/dl-tlsdesc.S b/ldso/ldso/xtensa/dl-tlsdesc.S index 426f2180b..1a8eacff2 100644 --- a/ldso/ldso/xtensa/dl-tlsdesc.S +++ b/ldso/ldso/xtensa/dl-tlsdesc.S @@ -24,6 +24,9 @@ .text HIDDEN_ENTRY (_dl_tlsdesc_return) +#ifdef __FDPIC__ + l32i a2, a2, 4 +#endif rur.threadptr a3 add a2, a2, a3 abi_ret @@ -53,7 +56,9 @@ END (_dl_tlsdesc_return) */ HIDDEN_ENTRY (_dl_tlsdesc_dynamic) - +#ifdef __FDPIC__ + l32i a2, a2, 4 +#endif /* dtv_t *dtv = (dtv_t *)THREAD_DTV(); */ rur.threadptr a3 l32i a4, a3, 0 @@ -86,7 +91,8 @@ HIDDEN_ENTRY (_dl_tlsdesc_dynamic) #elif defined(__XTENSA_CALL0_ABI__) addi a1, a1, -16 s32i a0, a1, 0 - movi a0, __tls_get_addr + movi a0, JUMPTARGET(__tls_get_addr) + FDPIC_LOAD_JUMPTARGET(a0, a11, a0) callx0 a0 l32i a0, a1, 0 addi a1, a1, 16 diff --git a/ldso/ldso/xtensa/elfinterp.c b/ldso/ldso/xtensa/elfinterp.c index e38a02666..d97f23435 100644 --- a/ldso/ldso/xtensa/elfinterp.c +++ b/ldso/ldso/xtensa/elfinterp.c @@ -36,6 +36,13 @@ #include "tlsdeschtab.h" #endif +#ifdef __FDPIC__ +unsigned long +_dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) +{ + return 0; +} +#else unsigned long _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) { @@ -83,7 +90,7 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) return (unsigned long) new_addr; } - +#endif static int _dl_parse (struct elf_resolve *tpnt, struct r_scope_elem *scope, @@ -145,8 +152,8 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, int reloc_type; int symtab_index; char *symname; -#if defined USE_TLS && USE_TLS - struct elf_resolve *tls_tpnt = NULL; +#if defined USE_TLS && USE_TLS || defined (__FDPIC__) + struct elf_resolve *def_mod = NULL; #endif struct symbol_ref sym_ref; ElfW(Addr) *reloc_addr; @@ -155,7 +162,7 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, ElfW(Addr) old_val; #endif - reloc_addr = (ElfW(Addr) *) (tpnt->loadaddr + rpnt->r_offset); + reloc_addr = (ElfW(Addr) *) DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_offset); reloc_type = ELF_R_TYPE (rpnt->r_info); symtab_index = ELF_R_SYM (rpnt->r_info); sym_ref.sym = &symtab[symtab_index]; @@ -164,9 +171,17 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, symname = strtab + sym_ref.sym->st_name; if (symtab_index) { - symbol_addr = (ElfW(Addr)) - _dl_find_hash (symname, scope, tpnt, - elf_machine_type_class (reloc_type), &sym_ref); + if (ELF_ST_BIND (sym_ref.sym->st_info) == STB_LOCAL) { + symbol_addr = (ElfW(Addr)) + DL_RELOC_ADDR(tpnt->loadaddr, + symtab[symtab_index].st_value); + sym_ref.tpnt = tpnt; + } else { + symbol_addr = (ElfW(Addr)) + _dl_find_hash (symname, scope, tpnt, + elf_machine_type_class (reloc_type), + &sym_ref); + } /* * We want to allow undefined references to weak symbols - this might @@ -182,13 +197,13 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], &sym_ref, elf_machine_type_class(reloc_type)); } -#if defined USE_TLS && USE_TLS - tls_tpnt = sym_ref.tpnt; +#if defined USE_TLS && USE_TLS || defined (__FDPIC__) + def_mod = sym_ref.tpnt; #endif } else { symbol_addr =symtab[symtab_index].st_value; -#if defined USE_TLS && USE_TLS - tls_tpnt = tpnt; +#if defined USE_TLS && USE_TLS || defined (__FDPIC__) + def_mod = tpnt; #endif } @@ -202,6 +217,7 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, case R_XTENSA_GLOB_DAT: case R_XTENSA_JMP_SLOT: + case R_XTENSA_SYM32: *reloc_addr = symbol_addr + rpnt->r_addend; break; @@ -219,19 +235,63 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, break; case R_XTENSA_RELATIVE: - *reloc_addr += tpnt->loadaddr + rpnt->r_addend; + *reloc_addr += DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_addend); break; +#ifdef __FDPIC__ + case R_XTENSA_FUNCDESC_VALUE: + { + struct funcdesc_value *dst = (struct funcdesc_value *) reloc_addr; + + dst->entry_point = (void *) (symbol_addr + rpnt->r_addend); + dst->got_value = def_mod->loadaddr.got_value; + } + break; + case R_XTENSA_FUNCDESC: + if (symbol_addr) + *reloc_addr = (unsigned long) + _dl_funcdesc_for((void *) (symbol_addr + rpnt->r_addend), + sym_ref.tpnt->loadaddr.got_value); + else + /* Relocation against an undefined weak symbol: + set funcdesc to zero. */ + *reloc_addr = 0; + break; + case R_XTENSA_TLS_TPOFF: + CHECK_STATIC_TLS((struct link_map *) def_mod); + *reloc_addr = symbol_addr + rpnt->r_addend + def_mod->l_tls_offset; + break; + case R_XTENSA_TLSDESC: + { + struct tlsdesc *td = (struct tlsdesc *) reloc_addr; +#ifndef SHARED + CHECK_STATIC_TLS((struct link_map *) def_mod); +#else + if (!TRY_STATIC_TLS ((struct link_map *) def_mod)) + { + td->entry = _dl_tlsdesc_dynamic; + td->argument = _dl_make_tlsdesc_dynamic((struct link_map *) def_mod, + symbol_addr + rpnt->r_addend); + } + else +#endif + { + td->entry = _dl_tlsdesc_return; + td->argument = (void *) (symbol_addr + rpnt->r_addend + def_mod->l_tls_offset); + } + } + break; +#else #if defined USE_TLS && USE_TLS case R_XTENSA_TLS_TPOFF: - CHECK_STATIC_TLS((struct link_map *) tls_tpnt); - *reloc_addr = symbol_addr + tls_tpnt->l_tls_offset + rpnt->r_addend; + CHECK_STATIC_TLS((struct link_map *) def_mod); + *reloc_addr = symbol_addr + rpnt->r_addend + def_mod->l_tls_offset; break; case R_XTENSA_TLSDESC_FN: #ifndef SHARED - CHECK_STATIC_TLS((struct link_map *) tls_tpnt); + CHECK_STATIC_TLS((struct link_map *) def_mod); #else - if (!TRY_STATIC_TLS ((struct link_map *) tls_tpnt)) + if (!TRY_STATIC_TLS ((struct link_map *) def_mod)) *reloc_addr = (ElfW(Addr)) _dl_tlsdesc_dynamic; else #endif @@ -239,25 +299,25 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, break; case R_XTENSA_TLSDESC_ARG: #ifndef SHARED - CHECK_STATIC_TLS((struct link_map *) tls_tpnt); + CHECK_STATIC_TLS((struct link_map *) def_mod); #else - if (!TRY_STATIC_TLS ((struct link_map *) tls_tpnt)) + if (!TRY_STATIC_TLS ((struct link_map *) def_mod)) *reloc_addr = (ElfW(Addr)) - _dl_make_tlsdesc_dynamic((struct link_map *) tls_tpnt, + _dl_make_tlsdesc_dynamic((struct link_map *) def_mod, symbol_addr + rpnt->r_addend); else #endif *reloc_addr = symbol_addr + rpnt->r_addend + - tls_tpnt->l_tls_offset; + def_mod->l_tls_offset; break; #endif - +#endif default: return -1; /* Calls _dl_exit(1). */ } #if defined (__SUPPORT_LD_DEBUG__) if (_dl_debug_reloc && _dl_debug_detail) - _dl_dprintf (_dl_debug_file, "\tpatched: %x ==> %x @ %x\n", + _dl_dprintf (_dl_debug_file, "\tpatched: %x ==> %x @ %p\n", old_val, *reloc_addr, reloc_addr); #endif @@ -275,7 +335,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, ElfW(Addr) old_val; #endif - reloc_addr = (ElfW(Addr) *) (tpnt->loadaddr + rpnt->r_offset); + reloc_addr = (ElfW(Addr) *) DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_offset); reloc_type = ELF_R_TYPE (rpnt->r_info); #if defined (__SUPPORT_LD_DEBUG__) @@ -286,7 +346,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, case R_XTENSA_JMP_SLOT: /* Perform a RELATIVE reloc on the GOT entry that transfers to the stub function. */ - *reloc_addr += tpnt->loadaddr; + *reloc_addr = DL_RELOC_ADDR(tpnt->loadaddr, *reloc_addr); break; case R_XTENSA_NONE: break; @@ -296,7 +356,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, #if defined (__SUPPORT_LD_DEBUG__) if (_dl_debug_reloc && _dl_debug_detail) - _dl_dprintf (_dl_debug_file, "\tpatched: %x ==> %x @ %x\n", + _dl_dprintf (_dl_debug_file, "\tpatched: %x ==> %x @ %p\n", old_val, *reloc_addr, reloc_addr); #endif return 0; @@ -320,3 +380,7 @@ _dl_parse_relocation_information (struct dyn_elf *rpnt, return _dl_parse (rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); } + +#ifndef IS_IN_libdl +# include "../../libc/sysdeps/linux/xtensa/crtreloc.c" +#endif diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c index 37c4a876e..6e50cb087 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -972,11 +972,11 @@ static int do_dlclose(void *vhandle, int need_fini) end = (end + ADDR_ALIGN) & PAGE_ALIGN; start = start & ~ADDR_ALIGN; if (end > start) { - _dl_if_debug_print("unmapping: %s at %p with length: '%p' until %p\n", tpnt->libname, tpnt->mapaddr, end - start, tpnt->mapaddr + (end - start)); + _dl_if_debug_print("unmapping: %s at %p with length: '%p' until %p\n", tpnt->libname, (void *)tpnt->mapaddr, (void *)(end - start), (void *)(tpnt->mapaddr + (end - start))); DL_LIB_UNMAP (tpnt, end - start); } else { - _dl_if_debug_print("NOT unmapping: %s at %p. start<end ('%p'<'%p')", tpnt->libname, tpnt->mapaddr, start, end); + _dl_if_debug_print("NOT unmapping: %s at %p. start<end ('%p'<'%p')", tpnt->libname, (void *)tpnt->mapaddr, (void *)start, (void *)end); } /* Free elements in RTLD_LOCAL scope list */ for (runp = tpnt->rtld_local; runp; runp = tmp) { diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index d7a659a8c..44685e6b8 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -1892,7 +1892,7 @@ int getnameinfo(const struct sockaddr *sa, socklen_t hostlen, char *serv, socklen_t servlen, - unsigned flags) + int flags) { int serrno = errno; bool ok = 0; @@ -2699,7 +2699,7 @@ int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen, hostp = __open_etc_hosts(); if (hostp == NULL) { *result = NULL; - ret = TRY_AGAIN; + *h_errnop = ret = TRY_AGAIN; goto DONE; } } diff --git a/libc/misc/auxvt/getauxval.c b/libc/misc/auxvt/getauxval.c index 2bdffaf2c..7610b7e5c 100755 --- a/libc/misc/auxvt/getauxval.c +++ b/libc/misc/auxvt/getauxval.c @@ -17,32 +17,28 @@ * <http://www.gnu.org/licenses/>. */ -#include "errno.h" -#include "ldso.h" -#include "sys/auxv.h" +#include <errno.h> +#include <ldso.h> +#include <sys/auxv.h> - -/* - * - * aarch64 gcc 11 uses __getauxval() in init_have_lse_atomics() - * - */ unsigned long int __getauxval (unsigned long int __type) { - if ( __type >= AUX_MAX_AT_ID ){ + // Requested value part of cached subset of auxiliary vector? + if (__type < AUX_MAX_AT_ID) { + if (_dl_auxvt[__type].a_type == __type) + return _dl_auxvt[__type].a_un.a_val; + __set_errno (ENOENT); return 0; } - if ( _dl_auxvt[__type].a_type == __type){ - return _dl_auxvt[__type].a_un.a_val; - } + // Otherwise we have to iterate the auxiliary vector. + for (ElfW(auxv_t) *entry = _dl_auxv_start; entry->a_type != AT_NULL; entry++) + if (entry->a_type == __type) + return entry->a_un.a_val; __set_errno (ENOENT); return 0; } -unsigned long int getauxval (unsigned long int __type){ - return __getauxval( __type ); -} - +weak_alias(__getauxval, getauxval) diff --git a/libc/misc/elf/dl-support.c b/libc/misc/elf/dl-support.c index 87cd1bb72..09cbefc18 100644 --- a/libc/misc/elf/dl-support.c +++ b/libc/misc/elf/dl-support.c @@ -12,6 +12,7 @@ */ #include <link.h> +#include <ldso.h> #include <elf.h> #if defined(USE_TLS) && USE_TLS #include <assert.h> @@ -31,17 +32,29 @@ ElfW(Phdr) *_dl_phdr; size_t _dl_phnum; size_t _dl_pagesize; +ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID]; +ElfW(auxv_t) *_dl_auxv_start; + void internal_function _dl_aux_init (ElfW(auxv_t) *av); void internal_function _dl_aux_init (ElfW(auxv_t) *av) { + _dl_auxv_start = av; + + memset(_dl_auxvt, 0x00, sizeof(_dl_auxvt)); + for (; av->a_type != AT_NULL; av++) + { + if (av->a_type < AUX_MAX_AT_ID) + _dl_auxvt[av->a_type] = *av; + } + /* Get the program headers base address from the aux vect */ - _dl_phdr = (ElfW(Phdr) *) av[AT_PHDR].a_un.a_val; + _dl_phdr = (ElfW(Phdr) *) _dl_auxvt[AT_PHDR].a_un.a_val; /* Get the number of program headers from the aux vect */ - _dl_phnum = (size_t) av[AT_PHNUM].a_un.a_val; + _dl_phnum = (size_t) _dl_auxvt[AT_PHNUM].a_un.a_val; /* Get the pagesize from the aux vect */ - _dl_pagesize = (av[AT_PAGESZ].a_un.a_val) ? (size_t) av[AT_PAGESZ].a_un.a_val : PAGE_SIZE; + _dl_pagesize = (_dl_auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) _dl_auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE; } #if defined(USE_TLS) && USE_TLS diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c index 64a9c8214..60695b6ed 100644 --- a/libc/misc/internals/__uClibc_main.c +++ b/libc/misc/internals/__uClibc_main.c @@ -43,7 +43,7 @@ /* Are we in a secure process environment or are we dealing * with setuid stuff? If we are dynamically linked, then we * already have _dl_secure, otherwise we need to re-examine - * auxvt[] below. + * _dl_auxvt[] below. */ int _pe_secure = 0; libc_hidden_data_def(_pe_secure) @@ -84,6 +84,8 @@ static void fdpic_init_array_jump(void *addr) #ifndef SHARED void *__libc_stack_end = NULL; +#include "dl-auxvt.h" + # ifdef __UCLIBC_HAS_SSP__ # include <dl-osinfo.h> static uintptr_t stack_chk_guard; @@ -373,7 +375,6 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc, { #ifndef SHARED unsigned long *aux_dat; - ElfW(auxv_t) auxvt[AT_EGID + 1]; #endif #ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -399,23 +400,14 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc, #ifndef SHARED /* Pull stuff from the ELF header when possible */ - memset(auxvt, 0x00, sizeof(auxvt)); aux_dat = (unsigned long*)__environ; while (*aux_dat) { aux_dat++; } aux_dat++; - while (*aux_dat) { - ElfW(auxv_t) *auxv_entry = (ElfW(auxv_t) *) aux_dat; - if (auxv_entry->a_type <= AT_EGID) { - memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(ElfW(auxv_t))); - } - aux_dat += 2; - } /* Get the program headers (_dl_phdr) from the aux vector It will be used into __libc_setup_tls. */ - - _dl_aux_init (auxvt); + _dl_aux_init ((ElfW(auxv_t) *)aux_dat); #endif /* We need to initialize uClibc. If we are dynamically linked this @@ -431,10 +423,10 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc, #ifndef SHARED /* Prevent starting SUID binaries where the stdin. stdout, and * stderr file descriptors are not already opened. */ - if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) || - (auxvt[AT_UID].a_un.a_val != (size_t)-1 && - (auxvt[AT_UID].a_un.a_val != auxvt[AT_EUID].a_un.a_val || - auxvt[AT_GID].a_un.a_val != auxvt[AT_EGID].a_un.a_val))) + if ((_dl_auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) || + (_dl_auxvt[AT_UID].a_un.a_val != (size_t)-1 && + (_dl_auxvt[AT_UID].a_un.a_val != _dl_auxvt[AT_EUID].a_un.a_val || + _dl_auxvt[AT_GID].a_un.a_val != _dl_auxvt[AT_EGID].a_un.a_val))) #else if (_dl_secure) #endif diff --git a/libc/misc/internals/reloc_static_pie.c b/libc/misc/internals/reloc_static_pie.c index 81af7d666..3bbdef18e 100644 --- a/libc/misc/internals/reloc_static_pie.c +++ b/libc/misc/internals/reloc_static_pie.c @@ -21,7 +21,7 @@ #include <dl-elf.h> #include <ldso.h> -#if defined(__mips__) || defined(__xtensa__) +#if defined(__m68k__) || defined(__mips__) || defined(__xtensa__) #include <dl-startup.h> #endif @@ -107,6 +107,8 @@ reloc_static_pie(ElfW(Addr) load_addr) PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, sym); } } +#else + (void)rel_size; #endif } _dl_load_base = load_addr; diff --git a/libc/misc/sysvipc/ipc.h b/libc/misc/sysvipc/ipc.h index b342dc1cf..58a690ee3 100644 --- a/libc/misc/sysvipc/ipc.h +++ b/libc/misc/sysvipc/ipc.h @@ -1,12 +1,19 @@ #ifndef IPC_H #define IPC_H #include <syscall.h> +#include <bits/kernel-features.h> #include <bits/wordsize.h> #ifndef __ARCH_HAS_DEPRECATED_SYSCALLS__ # define __IPC_64 0x0 +#elif defined __mips__ || defined __m68k__ +# if __LINUX_KERNEL_VERSION < 0x050100 +# define __IPC_64 0x100 +# else +# define __IPC_64 0x0 +# endif #else -# if __WORDSIZE == 32 || defined __alpha__ || defined __mips__ +# if __WORDSIZE == 32 || defined __alpha__ # define __IPC_64 0x100 # else # define __IPC_64 0x0 diff --git a/libc/misc/sysvipc/msgq.c b/libc/misc/sysvipc/msgq.c index 185cd268b..2d8bcae99 100644 --- a/libc/misc/sysvipc/msgq.c +++ b/libc/misc/sysvipc/msgq.c @@ -1,5 +1,6 @@ #include <errno.h> #include <sys/msg.h> +#include <stddef.h> #include "ipc.h" #ifdef __UCLIBC_HAS_THREADS_NATIVE__ #include "sysdep-cancel.h" @@ -7,6 +8,12 @@ #define SINGLE_THREAD_P 1 #endif +#if defined(__UCLIBC_USE_TIME64__) +union msqun { + struct msqid_ds* buff; + void *__pad; +}; +#endif #ifdef L_msgctl @@ -18,9 +25,19 @@ static __inline__ _syscall3(int, __libc_msgctl, int, msqid, int, cmd, struct msq int msgctl(int msqid, int cmd, struct msqid_ds *buf) { #ifdef __NR_msgctl - return __libc_msgctl(msqid, cmd | __IPC_64, buf); + int __ret = __libc_msgctl(msqid, cmd | __IPC_64, buf); +#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) && (defined(__mips) || defined(__riscv)) + union msqun arg = {.buff = buf}; + // When cmd is IPC_RMID, buf should be NULL. + if (arg.__pad != NULL) { + arg.buff->msg_stime = (__time_t)arg.buff->msg_stime_internal_1 | (__time_t)(arg.buff->msg_stime_internal_2) << 32; + arg.buff->msg_rtime = (__time_t)arg.buff->msg_rtime_internal_1 | (__time_t)(arg.buff->msg_rtime_internal_2) << 32; + arg.buff->msg_ctime = (__time_t)arg.buff->msg_ctime_internal_1 | (__time_t)(arg.buff->msg_ctime_internal_2) << 32; + } +#endif + return __ret; #else - return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf, 0); + return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf, 0); #endif } #endif diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index 07076eff7..66f86f53c 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -57,9 +57,14 @@ int semctl(int semid, int semnum, int cmd, ...) va_end (ap); #ifdef __NR_semctl int __ret = __semctl(semid, semnum, cmd | __IPC_64, arg.__pad); -#if defined(__UCLIBC_USE_TIME64__) - arg.buf->sem_otime = (__time_t)arg.buf->__sem_otime_internal_1 | (__time_t)(arg.buf->__sem_otime_internal_2) << 32; - arg.buf->sem_ctime = (__time_t)arg.buf->__sem_ctime_internal_1 | (__time_t)(arg.buf->__sem_ctime_internal_2) << 32; +#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) + // Only when cmd is IPC_STAT and IPC_SET, semun points to struct semid_ds. + // At this point, arg.__pad should not be NULL, but a check is added just + // to be safe. + if ((cmd & (IPC_STAT | IPC_SET)) && (arg.__pad != NULL)) { + arg.buf->sem_otime = (__time_t)arg.buf->__sem_otime_internal_1 | (__time_t)(arg.buf->__sem_otime_internal_2) << 32; + arg.buf->sem_ctime = (__time_t)arg.buf->__sem_ctime_internal_1 | (__time_t)(arg.buf->__sem_ctime_internal_2) << 32; + } #endif return __ret; #else diff --git a/libc/misc/sysvipc/shm.c b/libc/misc/sysvipc/shm.c index cd46ff0dd..b3366b301 100644 --- a/libc/misc/sysvipc/shm.c +++ b/libc/misc/sysvipc/shm.c @@ -25,6 +25,13 @@ #include <syscall.h> #include "ipc.h" +#if defined(__UCLIBC_USE_TIME64__) +union shmun { + struct shmid_ds* buff; + void *__pad; +}; +#endif + #ifdef L_shmat /* Attach the shared memory segment associated with SHMID to the data segment of the calling process. SHMADDR and SHMFLG determine how @@ -59,7 +66,17 @@ static __always_inline _syscall3(int, __syscall_shmctl, int, shmid, int, cmd, st int shmctl(int shmid, int cmd, struct shmid_ds *buf) { #ifdef __NR_shmctl - return __syscall_shmctl(shmid, cmd | __IPC_64, buf); + int __ret = __syscall_shmctl(shmid, cmd | __IPC_64, buf); +#if (__WORDSIZE == 32) && defined(__mips) && defined(__UCLIBC_USE_TIME64__) + union shmun arg = {.buff = buf}; + // When cmd is IPC_RMID, buf should be NULL. + if (arg.__pad != NULL) { + arg.buff->shm_atime = (__time_t)arg.buff->shm_atime_internal_1 | (__time_t)(arg.buff->shm_atime_internal_2) << 32; + arg.buff->shm_dtime = (__time_t)arg.buff->shm_dtime_internal_1 | (__time_t)(arg.buff->shm_dtime_internal_2) << 32; + arg.buff->shm_ctime = (__time_t)arg.buff->shm_ctime_internal_1 | (__time_t)(arg.buff->shm_ctime_internal_2) << 32; + } +#endif + return __ret; #else return __syscall_ipc(IPCOP_shmctl, shmid, cmd | __IPC_64, 0, buf, 0); #endif diff --git a/libc/misc/wchar/wchar.c b/libc/misc/wchar/wchar.c index 2714d47d7..782b67f93 100644 --- a/libc/misc/wchar/wchar.c +++ b/libc/misc/wchar/wchar.c @@ -1298,7 +1298,7 @@ iconv_t weak_function iconv_open(const char *tocode, const char *fromcode) int weak_function iconv_close(iconv_t cd) { - free(cd); + free((void *) cd); return 0; } diff --git a/libc/stdio/_fpmaxtostr.c b/libc/stdio/_fpmaxtostr.c index b06b25aa0..1f268fdaa 100644 --- a/libc/stdio/_fpmaxtostr.c +++ b/libc/stdio/_fpmaxtostr.c @@ -318,8 +318,8 @@ ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, #else /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */ -#define lower_bnd 1e8 -#define upper_bnd 1e9 +#define lower_bnd (__fpmax_t)1e8 +#define upper_bnd (__fpmax_t)1e9 #define power_table exp10_table #define dpb DIGITS_PER_BLOCK #define base 10 diff --git a/libc/stdio/_scanf.c b/libc/stdio/_scanf.c index 3f3000d6f..cb72d14ac 100644 --- a/libc/stdio/_scanf.c +++ b/libc/stdio/_scanf.c @@ -1715,7 +1715,7 @@ int attribute_hidden __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc) #define MAX_DIGITS 65 /* Allow one leading 0. */ unsigned char buf[MAX_DIGITS+2+ 100]; unsigned char usflag, base; - unsigned char nonzero = 0; + unsigned char nonzero __attribute__((unused)) = 0; unsigned char seendigit = 0; #ifndef __UCLIBC_HAS_FLOATS__ diff --git a/libc/stdlib/_strtod.c b/libc/stdlib/_strtod.c index c4c79e511..483551e64 100644 --- a/libc/stdlib/_strtod.c +++ b/libc/stdlib/_strtod.c @@ -256,7 +256,7 @@ __fpmax_t attribute_hidden __XL_NPP(__strtofpmax)(const Wchar *str, Wchar **endp } #endif - number = 0.; + number = (__fpmax_t)0; #ifdef _STRTOD_NEED_NUM_DIGITS num_digits = -1; #endif @@ -339,7 +339,7 @@ __fpmax_t attribute_hidden __XL_NPP(__strtofpmax)(const Wchar *str, Wchar **endp while ((pos[j] | 0x20) == nan_inf_str[i+1+j]) { ++j; if (!nan_inf_str[i+1+j]) { - number = i / 0.; + number = i / (__fpmax_t)0.; if (negative) { /* Correct for sign. */ number = -number; } @@ -414,7 +414,7 @@ __fpmax_t attribute_hidden __XL_NPP(__strtofpmax)(const Wchar *str, Wchar **endp } #ifdef _STRTOD_ZERO_CHECK - if (number == 0.) { + if (number == (__fpmax_t)0.) { goto DONE; } #endif @@ -515,7 +515,7 @@ float __XL_NPP(strtof)(const Wchar *str, Wchar **endptr __LOCALE_PARAM ) x = __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); y = (float) x; - __fp_range_check(y, x); + __fp_range_check((__fpmax_t)y, x); return y; #endif @@ -549,7 +549,7 @@ double __XL_NPP(strtod)(const Wchar *__restrict str, x = __XL_NPP(__strtofpmax)(str, endptr, 0 __LOCALE_ARG ); y = (double) x; - __fp_range_check(y, x); + __fp_range_check((__fpmax_t)y, x); return y; #endif diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c index cecea87ec..e51bc6610 100644 --- a/libc/stdlib/malloc-standard/malloc.c +++ b/libc/stdlib/malloc-standard/malloc.c @@ -29,7 +29,7 @@ __UCLIBC_MUTEX_INIT(__malloc_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); struct malloc_state __malloc_state; /* never directly referenced */ /* forward declaration */ -static int __malloc_largebin_index(unsigned int sz); +static int __malloc_largebin_index(unsigned long sz); #ifdef __UCLIBC_MALLOC_DEBUGGING__ @@ -755,10 +755,10 @@ static void* __malloc_alloc(size_t nb, mstate av) Compute index for size. We expect this to be inlined when compiled with optimization, else not, which works out well. */ -static int __malloc_largebin_index(unsigned int sz) +static int __malloc_largebin_index(unsigned long sz) { - unsigned int x = sz >> SMALLBIN_WIDTH; - unsigned int m; /* bit position of highest set bit of m */ + unsigned long x = sz >> SMALLBIN_WIDTH; + unsigned long m; /* bit position of highest set bit of m */ if (x >= 0x10000) return NBINS-1; @@ -776,7 +776,7 @@ static int __malloc_largebin_index(unsigned int sz) S. Warren Jr's book "Hacker's Delight". */ - unsigned int n = ((x - 0x100) >> 16) & 8; + unsigned long n = ((x - 0x100) >> 16) & 8; x <<= n; m = ((x - 0x1000) >> 16) & 4; n += m; diff --git a/libc/stdlib/malloc/memalign.c b/libc/stdlib/malloc/memalign.c index 665f20cfb..54f6dbc6c 100644 --- a/libc/stdlib/malloc/memalign.c +++ b/libc/stdlib/malloc/memalign.c @@ -11,6 +11,7 @@ * Written by Miles Bader <miles@gnu.org> */ +#include <errno.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> @@ -38,6 +39,11 @@ memalign (size_t alignment, size_t size) unsigned long tot_addr, tot_end_addr, addr, end_addr; struct heap_free_area **heap = &__malloc_heap; + if (unlikely(size > PTRDIFF_MAX)) { + __set_errno(ENOMEM); + return NULL; + } + /* Make SIZE something we like. */ size = HEAP_ADJUST_SIZE (size); diff --git a/libc/stdlib/stdlib.c b/libc/stdlib/stdlib.c index f5936630c..c45dd53a5 100644 --- a/libc/stdlib/stdlib.c +++ b/libc/stdlib/stdlib.c @@ -822,6 +822,7 @@ libc_hidden_def(_stdlib_mb_cur_max) #endif +#if defined(L_mblen) || defined(L_mbtowc) || defined(L_wctomb) #ifdef __UCLIBC_HAS_LOCALE__ /* * The following function return 1 if the encoding is stateful, 0 if stateless. @@ -844,6 +845,7 @@ static __always_inline int is_stateful(unsigned char encoding) #else #define is_stateful(encoding) 0 #endif +#endif /**********************************************************************/ #ifdef L_mblen diff --git a/libc/string/generic/strnlen.c b/libc/string/generic/strnlen.c index 4d4cde84f..82d4122ec 100644 --- a/libc/string/generic/strnlen.c +++ b/libc/string/generic/strnlen.c @@ -29,15 +29,17 @@ '\0' terminator is found in that many characters, return MAXLEN. */ size_t strnlen (const char *str, size_t maxlen) { - const char *char_ptr, *end_ptr = str + maxlen; + const char *char_ptr, *end_ptr; const unsigned long int *longword_ptr; unsigned long int longword, himagic, lomagic; if (maxlen == 0) return 0; - if (__builtin_expect (end_ptr < str, 0)) + if (__builtin_expect ((uintptr_t)str + maxlen < (uintptr_t)str, 0)) end_ptr = (const char *) ~0UL; + else + end_ptr = str + maxlen; /* Handle the first few characters by reading one character at a time. Do this until CHAR_PTR is aligned on a longword boundary. */ diff --git a/libc/string/x86_64/strcat.S b/libc/string/x86_64/strcat.S index 55e09e5f1..209e19062 100644 --- a/libc/string/x86_64/strcat.S +++ b/libc/string/x86_64/strcat.S @@ -106,7 +106,7 @@ ENTRY (BP_SYM (strcat)) /* Align, it is a jump target. */ /* Next 3 insns are 8 bytes total, make sure we decode them in one go */ - .p2align 3,,8 + .p2align 3,,7 3: subq $8,%rax /* correct pointer increment. */ diff --git a/libc/string/x86_64/strcspn.S b/libc/string/x86_64/strcspn.S index 7a06c8867..5ef565db7 100644 --- a/libc/string/x86_64/strcspn.S +++ b/libc/string/x86_64/strcspn.S @@ -94,7 +94,7 @@ L(1): leaq -4(%rdx), %rax /* prepare loop */ /* but it will also align entire function to 16 bytes, */ /* potentially creating largish padding at link time. */ /* We are aligning to 8 bytes instead: */ - .p2align 3,,8 + .p2align 3,,7 L(3): addq $4, %rax /* adjust pointer for full loop round */ diff --git a/libc/string/x86_64/strlen.S b/libc/string/x86_64/strlen.S index 9e84326c2..2fe2f58b2 100644 --- a/libc/string/x86_64/strlen.S +++ b/libc/string/x86_64/strlen.S @@ -102,7 +102,7 @@ ENTRY (strlen) /* Align, it is a jump target. */ /* Next 3 insns are 8 bytes total, make sure we decode them in one go */ - .p2align 3,,8 + .p2align 3,,7 3: subq $8,%rax /* correct pointer increment. */ diff --git a/libc/string/x86_64/strspn.S b/libc/string/x86_64/strspn.S index 366377649..8dc42656b 100644 --- a/libc/string/x86_64/strspn.S +++ b/libc/string/x86_64/strspn.S @@ -89,7 +89,7 @@ L(1): leaq -4(%rdx), %rax /* prepare loop */ /* but it will also align entire function to 16 bytes, */ /* potentially creating largish padding at link time. */ /* We are aligning to 8 bytes instead: */ - .p2align 3,,8 + .p2align 3,,7 L(3): addq $4, %rax /* adjust pointer for full loop round */ diff --git a/libc/sysdeps/linux/aarch64/bits/fcntl.h b/libc/sysdeps/linux/aarch64/bits/fcntl.h index dbe929351..024344eec 100644 --- a/libc/sysdeps/linux/aarch64/bits/fcntl.h +++ b/libc/sysdeps/linux/aarch64/bits/fcntl.h @@ -289,3 +289,6 @@ extern int fallocate64 (int __fd, int __mode, __off64_t __offset, #endif /* use GNU */ __END_DECLS + +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/aarch64/bits/fenv.h b/libc/sysdeps/linux/aarch64/bits/fenv.h new file mode 100644 index 000000000..4febd2177 --- /dev/null +++ b/libc/sysdeps/linux/aarch64/bits/fenv.h @@ -0,0 +1,78 @@ +/* Copyright (C) 2004-2025 Free Software Foundation, Inc. + + 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 bits representing exceptions in the FPSR status word. */ +enum + { + FE_INVALID = +#define FE_INVALID 1 + FE_INVALID, + FE_DIVBYZERO = +#define FE_DIVBYZERO 2 + FE_DIVBYZERO, + FE_OVERFLOW = +#define FE_OVERFLOW 4 + FE_OVERFLOW, + FE_UNDERFLOW = +#define FE_UNDERFLOW 8 + FE_UNDERFLOW, + FE_INEXACT = +#define FE_INEXACT 16 + FE_INEXACT, + }; + +/* Amount to shift by to convert an exception bit in FPSR to a an + exception bit mask in FPCR. */ +#define FE_EXCEPT_SHIFT 8 + +/* All supported exceptions. */ +#define FE_ALL_EXCEPT \ + (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) + +/* Define bits representing rounding modes in the FPCR Rmode field. */ +#define FE_TONEAREST 0x000000 +#define FE_UPWARD 0x400000 +#define FE_DOWNWARD 0x800000 +#define FE_TOWARDZERO 0xc00000 + +/* Type representing exception flags. */ +typedef unsigned int fexcept_t; + +/* Type representing floating-point environment. */ +typedef struct + { + unsigned int __fpcr; + unsigned int __fpsr; + } +fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((const fenv_t *) -1l) + +#ifdef __USE_GNU +/* Floating-point environment where none of the exceptions are masked. */ +# define FE_NOMASK_ENV ((const fenv_t *) -2) +#endif + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/aarch64/bits/shm.h b/libc/sysdeps/linux/aarch64/bits/shm.h new file mode 100644 index 000000000..bfb603499 --- /dev/null +++ b/libc/sysdeps/linux/aarch64/bits/shm.h @@ -0,0 +1,87 @@ +/* + * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB + * in this tarball. + */ + +#ifndef _SYS_SHM_H +# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead." +#endif + +#include <bits/types.h> + +/* Permission flag for shmget. */ +#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */ +#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */ + +/* Flags for `shmat'. */ +#define SHM_RDONLY 010000 /* attach read-only else read-write */ +#define SHM_RND 020000 /* round attach address to SHMLBA */ +#define SHM_REMAP 040000 /* take-over region on attach */ + +/* Commands for `shmctl'. */ +#define SHM_LOCK 11 /* lock segment (root only) */ +#define SHM_UNLOCK 12 /* unlock segment (root only) */ + +__BEGIN_DECLS + +/* Segment low boundary address multiple. */ +#define SHMLBA (__getpagesize () << 2) +extern int __getpagesize (void) __THROW __attribute__ ((__const__)); + + +/* Type to count number of attaches. */ +typedef unsigned long int shmatt_t; + +/* Data structure describing a set of semaphores. */ +struct shmid_ds + { + struct ipc_perm shm_perm; /* operation permission struct */ + size_t shm_segsz; /* size of segment in bytes */ + __time_t shm_atime; /* time of last shmat() */ + __time_t shm_dtime; /* time of last shmdt() */ + __time_t shm_ctime; /* time of last change by shmctl() */ + __pid_t shm_cpid; /* pid of creator */ + __pid_t shm_lpid; /* pid of last shmop */ + shmatt_t shm_nattch; /* number of current attaches */ + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; + }; + +#ifdef __USE_MISC + +/* ipcs ctl commands */ +# define SHM_STAT 13 +# define SHM_INFO 14 + +/* shm_mode upper byte flags */ +# define SHM_DEST 01000 /* segment will be destroyed on last detach */ +# define SHM_LOCKED 02000 /* segment will not be swapped */ +# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */ +# define SHM_NORESERVE 010000 /* don't check for reservations */ + +struct shminfo + { + unsigned long int shmmax; + unsigned long int shmmin; + unsigned long int shmmni; + unsigned long int shmseg; + unsigned long int shmall; + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; + unsigned long int __uclibc_unused3; + unsigned long int __uclibc_unused4; + }; + +struct shm_info + { + int used_ids; + unsigned long int shm_tot; /* total allocated shm */ + unsigned long int shm_rss; /* total resident shm */ + unsigned long int shm_swp; /* total swapped shm */ + unsigned long int swap_attempts; + unsigned long int swap_successes; + }; + +#endif /* __USE_MISC */ + +__END_DECLS diff --git a/libc/sysdeps/linux/aarch64/crt1.S b/libc/sysdeps/linux/aarch64/crt1.S index e9f946894..965d3265d 100644 --- a/libc/sysdeps/linux/aarch64/crt1.S +++ b/libc/sysdeps/linux/aarch64/crt1.S @@ -52,8 +52,8 @@ _start: /* Save off the atexit pointer */ mov x19, x0 - /* Calculate load address... idk how this works, but it does */ - adrp x0, _start + /* "Calculate" load address. The link address of __ehdr_start is 0. */ + adrp x0, __ehdr_start /* Do relocations */ bl reloc_static_pie diff --git a/libc/sysdeps/linux/aarch64/fpu_control.h b/libc/sysdeps/linux/aarch64/fpu_control.h new file mode 100644 index 000000000..c3e7f6629 --- /dev/null +++ b/libc/sysdeps/linux/aarch64/fpu_control.h @@ -0,0 +1,102 @@ +/* Copyright (C) 1996-2025 Free Software Foundation, Inc. + + 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 _AARCH64_FPU_CONTROL_H +#define _AARCH64_FPU_CONTROL_H + +#include <features.h> + +/* Macros for accessing the FPCR and FPSR. */ + +#if __GNUC_PREREQ (6,0) +# define _FPU_GETCW(fpcr) (fpcr = __builtin_aarch64_get_fpcr ()) +# define _FPU_SETCW(fpcr) __builtin_aarch64_set_fpcr (fpcr) +# define _FPU_GETFPSR(fpsr) (fpsr = __builtin_aarch64_get_fpsr ()) +# define _FPU_SETFPSR(fpsr) __builtin_aarch64_set_fpsr (fpsr) +#else +# define _FPU_GETCW(fpcr) \ + ({ \ + __uint64_t __fpcr; \ + __asm__ __volatile__ ("mrs %0, fpcr" : "=r" (__fpcr)); \ + fpcr = __fpcr; \ + }) + +# define _FPU_SETCW(fpcr) \ + ({ \ + __uint64_t __fpcr = fpcr; \ + __asm__ __volatile__ ("msr fpcr, %0" : : "r" (__fpcr)); \ + }) + +# define _FPU_GETFPSR(fpsr) \ + ({ \ + __uint64_t __fpsr; \ + __asm__ __volatile__ ("mrs %0, fpsr" : "=r" (__fpsr)); \ + fpsr = __fpsr; \ + }) + +# define _FPU_SETFPSR(fpsr) \ + ({ \ + __uint64_t __fpsr = fpsr; \ + __asm__ __volatile__ ("msr fpsr, %0" : : "r" (__fpsr)); \ + }) +#endif + +/* Reserved bits should be preserved when modifying register + contents. These two masks indicate which bits in each of FPCR and + FPSR should not be changed. */ + +#define _FPU_RESERVED 0xfe0fe0f8 +#define _FPU_FPSR_RESERVED 0x0fffffe0 + +#define _FPU_DEFAULT 0x00000000 +#define _FPU_FPSR_DEFAULT 0x00000000 + +/* Layout of FPCR and FPSR: + + | | | | | | | | + 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 + s s s s s s s s s s s + c c c c c c c c c c c c + N Z C V Q A D F R R S S S L L L I U U I U O D I I U U I U O D I + C H N Z M M T T B E E E D N N X F F Z O D N N X F F Z O + P O O R R Z N N N E K K E E E E E C K K C C C C C + D D I I P + E E D D + E E + */ + +#define _FPU_FPCR_RM_MASK 0xc00000 + +#define _FPU_FPCR_MASK_IXE 0x1000 +#define _FPU_FPCR_MASK_UFE 0x0800 +#define _FPU_FPCR_MASK_OFE 0x0400 +#define _FPU_FPCR_MASK_DZE 0x0200 +#define _FPU_FPCR_MASK_IOE 0x0100 + +#define _FPU_FPCR_IEEE \ + (_FPU_DEFAULT | _FPU_FPCR_MASK_IXE \ + | _FPU_FPCR_MASK_UFE | _FPU_FPCR_MASK_OFE \ + | _FPU_FPCR_MASK_DZE | _FPU_FPCR_MASK_IOE) + +#define _FPU_FPSR_IEEE 0 + +typedef unsigned int fpu_control_t; +typedef unsigned int fpu_fpsr_t; + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif diff --git a/libc/sysdeps/linux/aarch64/sys/ucontext.h b/libc/sysdeps/linux/aarch64/sys/ucontext.h index 5f75cbbf3..1a27f918b 100644 --- a/libc/sysdeps/linux/aarch64/sys/ucontext.h +++ b/libc/sysdeps/linux/aarch64/sys/ucontext.h @@ -45,10 +45,10 @@ typedef elf_fpregset_t fpregset_t; typedef struct sigcontext mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { unsigned long uc_flags; - struct ucontext_t *uc_link; + struct ucontext *uc_link; stack_t uc_stack; __sigset_t uc_sigmask; unsigned char __reserved[128]; diff --git a/libc/sysdeps/linux/alpha/bits/fcntl.h b/libc/sysdeps/linux/alpha/bits/fcntl.h index 11e68214e..7d06c76b7 100644 --- a/libc/sysdeps/linux/alpha/bits/fcntl.h +++ b/libc/sysdeps/linux/alpha/bits/fcntl.h @@ -236,3 +236,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/alpha/bits/stat.h b/libc/sysdeps/linux/alpha/bits/stat.h index 88bc6617d..f2dca250d 100644 --- a/libc/sysdeps/linux/alpha/bits/stat.h +++ b/libc/sysdeps/linux/alpha/bits/stat.h @@ -40,7 +40,7 @@ Use neat tidy anonymous unions and structures when possible. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) # if __GNUC_PREREQ(3,3) # define __ST_TIME(X) \ __extension__ union { \ diff --git a/libc/sysdeps/linux/arc/bits/fcntl.h b/libc/sysdeps/linux/arc/bits/fcntl.h index beb32e41e..b02849691 100755 --- a/libc/sysdeps/linux/arc/bits/fcntl.h +++ b/libc/sysdeps/linux/arc/bits/fcntl.h @@ -230,3 +230,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS + +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/arc/bits/fenv.h b/libc/sysdeps/linux/arc/bits/fenv.h new file mode 100644 index 000000000..c5c76cb93 --- /dev/null +++ b/libc/sysdeps/linux/arc/bits/fenv.h @@ -0,0 +1,75 @@ +/* Floating point environment. ARC version. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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 + +enum + { + FE_INVALID = +# define FE_INVALID (0x01) + FE_INVALID, + FE_DIVBYZERO = +# define FE_DIVBYZERO (0x02) + FE_DIVBYZERO, + FE_OVERFLOW = +# define FE_OVERFLOW (0x04) + FE_OVERFLOW, + FE_UNDERFLOW = +# define FE_UNDERFLOW (0x08) + FE_UNDERFLOW, + FE_INEXACT = +# define FE_INEXACT (0x10) + FE_INEXACT + }; + +# define FE_ALL_EXCEPT \ + (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) + +enum + { + FE_TOWARDZERO = +# define FE_TOWARDZERO (0x0) + FE_TOWARDZERO, + FE_TONEAREST = +# define FE_TONEAREST (0x1) /* default */ + FE_TONEAREST, + FE_UPWARD = +# define FE_UPWARD (0x2) + FE_UPWARD, + FE_DOWNWARD = +# define FE_DOWNWARD (0x3) + FE_DOWNWARD + }; + +typedef unsigned int fexcept_t; + +typedef struct +{ + unsigned int __fpcr; + unsigned int __fpsr; +} fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((const fenv_t *) -1) + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/arc/fpu_control.h b/libc/sysdeps/linux/arc/fpu_control.h new file mode 100644 index 000000000..e833de3aa --- /dev/null +++ b/libc/sysdeps/linux/arc/fpu_control.h @@ -0,0 +1,104 @@ +/* FPU control word bits. ARC version. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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 _FPU_CONTROL_H +#define _FPU_CONTROL_H + +/* ARC FPU control register bits. + + [ 0] -> IVE: Enable invalid operation exception. + if 0, soft exception: status register IV flag set. + if 1, hardware exception trap (not supported in Linux yet). + [ 1] -> DZE: Enable division by zero exception. + if 0, soft exception: status register IV flag set. + if 1, hardware exception: (not supported in Linux yet). + [9:8] -> RM: Rounding Mode: + 00 - Rounding toward zero. + 01 - Rounding to nearest (default). + 10 - Rounding (up) toward plus infinity. + 11 - Rounding (down)toward minus infinity. + + ARC FPU status register bits. + + [ 0] -> IV: flag invalid operation. + [ 1] -> DZ: flag division by zero. + [ 2] -> OV: flag Overflow operation. + [ 3] -> UV: flag Underflow operation. + [ 4] -> IX: flag Inexact operation. + [31] -> FWE: Flag Write Enable. + If 1, above flags writable explicitly (clearing), + else IoW and only writable indirectly via bits [12:7]. */ + +#include <features.h> + +#if !defined(__ARC_FPU_SP__) && !defined(__ARC_FPU_DP__) + +# 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) +# define _FPU_GETS(cw) (cw) = 0 +# define _FPU_SETS(cw) (void) (cw) +extern fpu_control_t __fpu_control; + +#else + +#define _FPU_RESERVED 0 + +/* The fdlibm code requires strict IEEE double precision arithmetic, + and no interrupts for exceptions, rounding to nearest. + So only RM set to b'01. */ +# define _FPU_DEFAULT 0x00000100 + +/* Actually default needs to have FWE bit as 1 but that is already + ingrained into _FPU_SETS macro below. */ +#define _FPU_FPSR_DEFAULT 0x00000000 + +#define __FPU_RND_SHIFT 8 +#define __FPU_RND_MASK 0x3 + +/* Type of the control word. */ +typedef unsigned int fpu_control_t; + +/* Macros for accessing the hardware control word. */ +# define _FPU_GETCW(cw) __asm__ volatile ("lr %0, [0x300]" : "=r" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("sr %0, [0x300]" : : "r" (cw)) + +/* Macros for accessing the hardware status word. + Writing to FPU_STATUS requires a "control" bit FWE to be able to set the + exception flags directly (as opposed to side-effects of FP instructions). + That is done in the macro here to keeps callers agnostic of this detail. + And given FWE is write-only and RAZ, no need to "clear" it in _FPU_GETS + macro. */ +# define _FPU_GETS(cw) \ + __asm__ volatile ("lr %0, [0x301] \r\n" \ + : "=r" (cw)) + +# define _FPU_SETS(cw) \ + do { \ + unsigned int __fwe = 0x80000000 | (cw); \ + __asm__ volatile ("sr %0, [0x301] \r\n" \ + : : "r" (__fwe)); \ + } while (0) + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif + +#endif /* fpu_control.h */ diff --git a/libc/sysdeps/linux/arm/__longjmp.S b/libc/sysdeps/linux/arm/__longjmp.S index 58ae8ab58..a5ffe84e9 100644 --- a/libc/sysdeps/linux/arm/__longjmp.S +++ b/libc/sysdeps/linux/arm/__longjmp.S @@ -64,6 +64,13 @@ __longjmp: #if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__ #ifdef __VFP_FP__ +# if __ARM_ARCH >= 8 + /* Restore the VFP registers. */ + fldmiax ip!, {d8-d15} + /* Restore the floating-point status register. */ + ldr r1, [ip], #4 + fmxr fpscr, r1 +# else /* Restore the VFP registers. */ /* Following instruction is fldmiax ip!, {d8-d15}. */ ldc p11, cr8, [r12], #68 @@ -71,6 +78,7 @@ __longjmp: ldr r1, [ip], #4 /* Following instruction is fmxr fpscr, r1. */ mcr p10, 7, r1, cr1, cr0, 0 +# endif # elif defined __MAVERICK__ cfldrd mvd4, [ip], #8 ; nop cfldrd mvd5, [ip], #8 ; nop diff --git a/libc/sysdeps/linux/arm/bits/fcntl.h b/libc/sysdeps/linux/arm/bits/fcntl.h index 823660648..52dee4287 100644 --- a/libc/sysdeps/linux/arm/bits/fcntl.h +++ b/libc/sysdeps/linux/arm/bits/fcntl.h @@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/arm/bits/fenv.h b/libc/sysdeps/linux/arm/bits/fenv.h index 106bf36c2..ab60b9e70 100644 --- a/libc/sysdeps/linux/arm/bits/fenv.h +++ b/libc/sysdeps/linux/arm/bits/fenv.h @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* Copyright (C) 2004-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -12,87 +11,77 @@ 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 - <http://www.gnu.org/licenses/>. */ + 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 -#ifdef __MAVERICK__ - /* Define bits representing exceptions in the FPU status word. */ enum { - FE_INVALID = 1, -#define FE_INVALID FE_INVALID - FE_OVERFLOW = 4, -#define FE_OVERFLOW FE_OVERFLOW - FE_UNDERFLOW = 8, -#define FE_UNDERFLOW FE_UNDERFLOW - FE_INEXACT = 16, -#define FE_INEXACT FE_INEXACT + FE_INVALID = +#define FE_INVALID 1 + FE_INVALID, + FE_DIVBYZERO = +#define FE_DIVBYZERO 2 + FE_DIVBYZERO, + FE_OVERFLOW = +#define FE_OVERFLOW 4 + FE_OVERFLOW, + FE_UNDERFLOW = +#define FE_UNDERFLOW 8 + FE_UNDERFLOW, + FE_INEXACT = +#define FE_INEXACT 16 + FE_INEXACT, }; /* Amount to shift by to convert an exception to a mask bit. */ -#define FE_EXCEPT_SHIFT 5 +#define FE_EXCEPT_SHIFT 8 /* All supported exceptions. */ -#define FE_ALL_EXCEPT \ - (FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) - -/* IEEE rounding modes. */ -enum - { - FE_TONEAREST = 0, -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = 0x400, -#define FE_TOWARDZERO FE_TOWARDZERO - FE_DOWNWARD = 0x800, -#define FE_DOWNWARD FE_DOWNWARD - FE_UPWARD = 0xc00, -#define FE_UPWARD FE_UPWARD - }; - -#define FE_ROUND_MASK (FE_UPWARD) - -#else /* !__MAVERICK__ */ +#define FE_ALL_EXCEPT \ + (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) -/* Define bits representing exceptions in the FPU status word. */ +/* VFP supports all of the four defined rounding modes. */ enum { - FE_INVALID = 1, -#define FE_INVALID FE_INVALID - FE_DIVBYZERO = 2, -#define FE_DIVBYZERO FE_DIVBYZERO - FE_OVERFLOW = 4, -#define FE_OVERFLOW FE_OVERFLOW - FE_UNDERFLOW = 8, -#define FE_UNDERFLOW FE_UNDERFLOW - }; - -/* Amount to shift by to convert an exception to a mask bit. */ -#define FE_EXCEPT_SHIFT 16 - -/* All supported exceptions. */ -#define FE_ALL_EXCEPT \ - (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) - -/* The ARM FPU basically only supports round-to-nearest. Other rounding - modes exist, but you have to encode them in the actual instruction. */ + FE_TONEAREST = #define FE_TONEAREST 0 - -#endif /* __MAVERICK__ */ + FE_TONEAREST, + FE_UPWARD = +#define FE_UPWARD 0x400000 + FE_UPWARD, + FE_DOWNWARD = +#define FE_DOWNWARD 0x800000 + FE_DOWNWARD, + FE_TOWARDZERO = +#define FE_TOWARDZERO 0xc00000 + FE_TOWARDZERO + }; /* Type representing exception flags. */ -typedef unsigned long int fexcept_t; +typedef unsigned int fexcept_t; /* Type representing floating-point environment. */ typedef struct { - unsigned long int __cw; + unsigned int __cw; } fenv_t; /* If the default argument is used we use this value. */ -#define FE_DFL_ENV ((fenv_t *) -1l) +#define FE_DFL_ENV ((const fenv_t *) -1l) + +#ifdef __USE_GNU +/* Floating-point environment where none of the exceptions are masked. */ +# define FE_NOMASK_ENV ((const fenv_t *) -2) +#endif + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/arm/bits/shm.h b/libc/sysdeps/linux/arm/bits/shm.h index 86245faff..aa1a72e54 100644 --- a/libc/sysdeps/linux/arm/bits/shm.h +++ b/libc/sysdeps/linux/arm/bits/shm.h @@ -49,12 +49,18 @@ struct shmid_ds { struct ipc_perm shm_perm; /* operation permission struct */ size_t shm_segsz; /* size of segment in bytes */ +#if defined(__UCLIBC_USE_TIME64__) + __time_t shm_atime; + __time_t shm_dtime; + __time_t shm_ctime; +#else __time_t shm_atime; /* time of last shmat() */ unsigned long int __uclibc_unused1; __time_t shm_dtime; /* time of last shmdt() */ unsigned long int __uclibc_unused2; __time_t shm_ctime; /* time of last change by shmctl() */ unsigned long int __uclibc_unused3; +#endif __pid_t shm_cpid; /* pid of creator */ __pid_t shm_lpid; /* pid of last shmop */ shmatt_t shm_nattch; /* number of current attaches */ diff --git a/libc/sysdeps/linux/arm/crt1.S b/libc/sysdeps/linux/arm/crt1.S index 799f11080..040ddfd27 100644 --- a/libc/sysdeps/linux/arm/crt1.S +++ b/libc/sysdeps/linux/arm/crt1.S @@ -248,13 +248,9 @@ _start: #if defined(__ARCH_USE_MMU__) || defined(__UCLIBC_FORMAT_ELF__) #ifdef L_rcrt1 /* We don't need to save a1 since no dynamic linker should have run */ - ldr a1, .L_GOT /* Get value at .L_GOT + 0 (offset to GOT)*/ - adr a2, .L_GOT /* Get address of .L_GOT */ - ldr a3, .L_GOT+16 /* Get value of _start(GOT) stored in .L_GOT */ - adr a4, _start /* Get address of _start after relocation (changes to pc - ~30 or so) */ - add a1, a1, a2 /* Calculate where the GOT is */ - ldr a2, [a1, a3] /* GOT + _start(GOT) = offset of _start from begin of file */ - sub a1, a4, a2 /* Current addr of _start - offset from beginning of file = load addr */ + adr a1, .L__ehdr_start_off /* Get address of .L__ehdr_start_off */ + ldr a2, .L__ehdr_start_off /* Offset from .L__ehdr_start_off to __ehdr_start */ + add a1, a1, a2 /* Address of __ehdr_start = load addr */ bl reloc_static_pie mov a1, #0 /* Clean up a1 so that a random address won't get called at the end of program */ @@ -325,9 +321,10 @@ _start: .word _fini(GOT) .word _init(GOT) .word main(GOT) -#ifdef L_rcrt1 - .word _start(GOT) #endif +#ifdef L_rcrt1 +.L__ehdr_start_off: + .word __ehdr_start - .L__ehdr_start_off #endif #endif diff --git a/libc/sysdeps/linux/arm/fpu_control.h b/libc/sysdeps/linux/arm/fpu_control.h index 1b9b09df6..05ac6a03c 100644 --- a/libc/sysdeps/linux/arm/fpu_control.h +++ b/libc/sysdeps/linux/arm/fpu_control.h @@ -1,6 +1,5 @@ -/* FPU control word definitions. ARM version. - Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* FPU control word definitions. ARM VFP version. + Copyright (C) 2004-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -13,13 +12,22 @@ 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 - <http://www.gnu.org/licenses/>. */ + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ #ifndef _FPU_CONTROL_H #define _FPU_CONTROL_H -#ifdef __VFP_FP__ +#if !(defined(_LIBC) && !defined(_LIBC_TEST)) && defined(__SOFTFP__) + +#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 /* masking of interrupts */ #define _FPU_MASK_IM 0x00000100 /* invalid operation */ @@ -28,175 +36,39 @@ #define _FPU_MASK_UM 0x00000800 /* underflow */ #define _FPU_MASK_PM 0x00001000 /* inexact */ +#define _FPU_MASK_NZCV 0xf0000000 /* NZCV flags */ +#define _FPU_MASK_RM 0x00c00000 /* rounding mode */ +#define _FPU_MASK_EXCEPT 0x00001f1f /* all exception flags */ + /* Some bits in the FPSCR are not yet defined. They must be preserved when modifying the contents. */ -#define _FPU_RESERVED 0x0e08e0e0 +#define _FPU_RESERVED 0x00086060 #define _FPU_DEFAULT 0x00000000 -/* Default + exceptions enabled. */ + +/* Default + exceptions enabled. */ #define _FPU_IEEE (_FPU_DEFAULT | 0x00001f00) /* Type of the control word. */ typedef unsigned int fpu_control_t; /* Macros for accessing the hardware control word. */ +#ifdef __SOFTFP__ /* This is fmrx %0, fpscr. */ -#define _FPU_GETCW(cw) \ +# define _FPU_GETCW(cw) \ __asm__ __volatile__ ("mrc p10, 7, %0, cr1, cr0, 0" : "=r" (cw)) /* This is fmxr fpscr, %0. */ -#define _FPU_SETCW(cw) \ +# define _FPU_SETCW(cw) \ __asm__ __volatile__ ("mcr p10, 7, %0, cr1, cr0, 0" : : "r" (cw)) +#else +# define _FPU_GETCW(cw) \ + __asm__ __volatile__ ("vmrs %0, fpscr" : "=r" (cw)) +# define _FPU_SETCW(cw) \ + __asm__ __volatile__ ("vmsr fpscr, %0" : : "r" (cw)) +#endif -#elif defined __MAVERICK__ - -/* DSPSC register: (from EP9312 User's Guide) - * - * bits 31..29 - DAID - * bits 28..26 - HVID - * bits 25..24 - RSVD - * bit 23 - ISAT - * bit 22 - UI - * bit 21 - INT - * bit 20 - AEXC - * bits 19..18 - SAT - * bits 17..16 - FCC - * bit 15 - V - * bit 14 - FWDEN - * bit 13 - Invalid - * bit 12 - Denorm - * bits 11..10 - RM - * bits 9..5 - IXE, UFE, OFE, RSVD, IOE - * bits 4..0 - IX, UF, OF, RSVD, IO - */ - -/* masking of interrupts */ -#define _FPU_MASK_IM (1 << 5) /* invalid operation */ -#define _FPU_MASK_ZM 0 /* divide by zero */ -#define _FPU_MASK_OM (1 << 7) /* overflow */ -#define _FPU_MASK_UM (1 << 8) /* underflow */ -#define _FPU_MASK_PM (1 << 9) /* inexact */ -#define _FPU_MASK_DM 0 /* denormalized operation */ - -#define _FPU_RESERVED 0xfffff000 /* These bits are reserved. */ - -#define _FPU_DEFAULT 0x00b00000 /* Default value. */ -#define _FPU_IEEE 0x00b003a0 /* Default + exceptions enabled. */ - -/* Type of the control word. */ -typedef unsigned int fpu_control_t; - -/* Macros for accessing the hardware control word. */ -#define _FPU_GETCW(cw) ({ \ - register int __t1, __t2; \ - \ - __asm__ __volatile__ ( \ - "cfmvr64l %1, mvdx0\n\t" \ - "cfmvr64h %2, mvdx0\n\t" \ - "cfmv32sc mvdx0, dspsc\n\t" \ - "cfmvr64l %0, mvdx0\n\t" \ - "cfmv64lr mvdx0, %1\n\t" \ - "cfmv64hr mvdx0, %2" \ - : "=r" (cw), "=r" (__t1), "=r" (__t2) \ - ); \ -}) - -#define _FPU_SETCW(cw) ({ \ - register int __t0, __t1, __t2; \ - \ - __asm__ __volatile__ ( \ - "cfmvr64l %1, mvdx0\n\t" \ - "cfmvr64h %2, mvdx0\n\t" \ - "cfmv64lr mvdx0, %0\n\t" \ - "cfmvsc32 dspsc, mvdx0\n\t" \ - "cfmv64lr mvdx0, %1\n\t" \ - "cfmv64hr mvdx0, %2" \ - : "=r" (__t0), "=r" (__t1), "=r" (__t2) \ - : "0" (cw) \ - ); \ -}) - -#else /* !__MAVERICK__ */ - -/* We have a slight terminology confusion here. On the ARM, the register - * we're interested in is actually the FPU status word - the FPU control - * word is something different (which is implementation-defined and only - * accessible from supervisor mode.) - * - * The FPSR looks like this: - * - * 31-24 23-16 15-8 7-0 - * | system ID | trap enable | system control | exception flags | - * - * We ignore the system ID bits; for interest's sake they are: - * - * 0000 "old" FPE - * 1000 FPPC hardware - * 0001 FPE 400 - * 1001 FPA hardware - * - * The trap enable and exception flags are both structured like this: - * - * 7 - 5 4 3 2 1 0 - * | reserved | INX | UFL | OFL | DVZ | IVO | - * - * where a `1' bit in the enable byte means that the trap can occur, and - * a `1' bit in the flags byte means the exception has occurred. - * - * The exceptions are: - * - * IVO - invalid operation - * DVZ - divide by zero - * OFL - overflow - * UFL - underflow - * INX - inexact (do not use; implementations differ) - * - * The system control byte looks like this: - * - * 7-5 4 3 2 1 0 - * | reserved | AC | EP | SO | NE | ND | - * - * where the bits mean - * - * ND - no denormalised numbers (force them all to zero) - * NE - enable NaN exceptions - * SO - synchronous operation - * EP - use expanded packed-decimal format - * AC - use alternate definition for C flag on compare operations - */ - -/* masking of interrupts */ -#define _FPU_MASK_IM 0x00010000 /* invalid operation */ -#define _FPU_MASK_ZM 0x00020000 /* divide by zero */ -#define _FPU_MASK_OM 0x00040000 /* overflow */ -#define _FPU_MASK_UM 0x00080000 /* underflow */ -#define _FPU_MASK_PM 0x00100000 /* inexact */ -#define _FPU_MASK_DM 0x00000000 /* denormalized operation */ - -/* The system id bytes cannot be changed. - Only the bottom 5 bits in the trap enable byte can be changed. - Only the bottom 5 bits in the system control byte can be changed. - Only the bottom 5 bits in the exception flags are used. - The exception flags are set by the fpu, but can be zeroed by the user. */ -#define _FPU_RESERVED 0xffe0e0e0 /* These bits are reserved. */ - -/* The fdlibm code requires strict IEEE double precision arithmetic, - no interrupts for exceptions, rounding to nearest. Changing the - rounding mode will break long double I/O. Turn on the AC bit, - the compiler generates code that assumes it is on. */ -#define _FPU_DEFAULT 0x00001000 /* Default value. */ -#define _FPU_IEEE 0x001f1000 /* Default + exceptions enabled. */ - -/* Type of the control word. */ -typedef unsigned int fpu_control_t; - -/* Macros for accessing the hardware control word. */ -#define _FPU_GETCW(cw) __asm__ ("rfs %0" : "=r" (cw)) -#define _FPU_SETCW(cw) __asm__ ("wfs %0" : : "r" (cw)) - -#endif /* __MAVERICK__ */ - -#if 0 /* Default control word set at startup. */ extern fpu_control_t __fpu_control; -#endif + +#endif /* __SOFTFP__ */ #endif /* _FPU_CONTROL_H */ diff --git a/libc/sysdeps/linux/arm/setjmp.S b/libc/sysdeps/linux/arm/setjmp.S index f7a74cc5a..d5bc9ba65 100644 --- a/libc/sysdeps/linux/arm/setjmp.S +++ b/libc/sysdeps/linux/arm/setjmp.S @@ -54,6 +54,13 @@ __sigsetjmp: #endif #if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__ # ifdef __VFP_FP__ +# if __ARM_ARCH >= 8 + /* Store the VFP registers. */ + fstmiax ip!, {d8-d15} + /* Store the floating-point status register. */ + fmrx r2, fpscr + str r2, [ip], #4 +# else /* Store the VFP registers. */ /* Following instruction is fstmiax ip!, {d8-d15}. */ stc p11, cr8, [r12], #68 @@ -61,6 +68,7 @@ __sigsetjmp: /* Following instruction is fmrx r2, fpscr. */ mrc p10, 7, r2, cr1, cr0, 0 str r2, [ip], #4 +# endif # elif defined __MAVERICK__ cfstrd mvd4, [ip], #8 ; nop cfstrd mvd5, [ip], #8 ; nop diff --git a/libc/sysdeps/linux/avr32/bits/fcntl.h b/libc/sysdeps/linux/avr32/bits/fcntl.h index ec0a3b55d..9e41550be 100644 --- a/libc/sysdeps/linux/avr32/bits/fcntl.h +++ b/libc/sysdeps/linux/avr32/bits/fcntl.h @@ -218,3 +218,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, __END_DECLS #endif + +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/bfin/bits/fcntl.h b/libc/sysdeps/linux/bfin/bits/fcntl.h index 0909ae6c4..67d2c5245 100644 --- a/libc/sysdeps/linux/bfin/bits/fcntl.h +++ b/libc/sysdeps/linux/bfin/bits/fcntl.h @@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/c6x/bits/fcntl.h b/libc/sysdeps/linux/c6x/bits/fcntl.h index 14aea565e..00f3b34e0 100644 --- a/libc/sysdeps/linux/c6x/bits/fcntl.h +++ b/libc/sysdeps/linux/c6x/bits/fcntl.h @@ -237,3 +237,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS + +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/common-generic/bits/kernel_stat.h b/libc/sysdeps/linux/common-generic/bits/kernel_stat.h index 7a97bb4d7..e874a4a9f 100644 --- a/libc/sysdeps/linux/common-generic/bits/kernel_stat.h +++ b/libc/sysdeps/linux/common-generic/bits/kernel_stat.h @@ -18,7 +18,7 @@ * However that requires more #ifndef in relevant wrappers, * further uglifying them */ -#define kernel_stat64 stat +#define kernel_stat64 stat64 #endif /* _BITS_STAT_STRUCT_H */ diff --git a/libc/sysdeps/linux/common/Makefile.in b/libc/sysdeps/linux/common/Makefile.in index 848bc1e4a..4a4317432 100644 --- a/libc/sysdeps/linux/common/Makefile.in +++ b/libc/sysdeps/linux/common/Makefile.in @@ -27,9 +27,11 @@ CSRC-$(UCLIBC_LINUX_SPECIFIC) += \ eventfd_write.c \ fanotify.c \ getrandom.c \ + getentropy.c \ inotify.c \ ioperm.c \ iopl.c \ + memfd_create.c \ modify_ldt.c \ module.c \ name_to_handle_at.c \ @@ -39,6 +41,8 @@ CSRC-$(UCLIBC_LINUX_SPECIFIC) += \ ppoll.c \ prctl.c \ prlimit.c \ + process_vm_readv.c \ + process_vm_writev.c \ readahead.c \ reboot.c \ remap_file_pages.c \ diff --git a/libc/sysdeps/linux/common/adjtimex.c b/libc/sysdeps/linux/common/adjtimex.c index f45d54371..2fd7977f6 100644 --- a/libc/sysdeps/linux/common/adjtimex.c +++ b/libc/sysdeps/linux/common/adjtimex.c @@ -9,8 +9,16 @@ #include <sys/syscall.h> #include <sys/timex.h> - +#if defined(__NR_adjtimex) _syscall1(int, adjtimex, struct timex *, buf) +#else +#include <time.h> +int adjtimex(struct timex *buf) +{ + return clock_adjtime(CLOCK_REALTIME, buf); +} +#endif + libc_hidden_def(adjtimex) weak_alias(adjtimex,__adjtimex) #if defined __UCLIBC_NTP_LEGACY__ diff --git a/libc/sysdeps/linux/common/bits/fcntl-linux.h b/libc/sysdeps/linux/common/bits/fcntl-linux.h new file mode 100644 index 000000000..d0236fd8b --- /dev/null +++ b/libc/sysdeps/linux/common/bits/fcntl-linux.h @@ -0,0 +1,34 @@ +/* O_*, F_*, FD_* bit values for Linux. + Copyright (C) 2001-2024 Free Software Foundation, Inc. + + 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 _FCNTL_H +# error "Never use <bits/fcntl-linux.h> directly; include <fcntl.h> instead." +#endif + +#ifdef __USE_GNU +/* Types of seals. */ +# define F_SEAL_SEAL 0x0001 /* Prevent further seals from being set. */ +# define F_SEAL_SHRINK 0x0002 /* Prevent file from shrinking. */ +# define F_SEAL_GROW 0x0004 /* Prevent file from growing. */ +# define F_SEAL_WRITE 0x0008 /* Prevent writes. */ +# define F_SEAL_FUTURE_WRITE 0x0010 /* Prevent future writes while + mapped. */ +# define F_SEAL_EXEC 0x0020 /* Prevent chmod modifying exec bits. */ + +# define F_ADD_SEALS 1033 /* Add seals to file. */ +# define F_GET_SEALS 1034 /* Get seals for file. */ +#endif diff --git a/libc/sysdeps/linux/common/bits/mman-shared.h b/libc/sysdeps/linux/common/bits/mman-shared.h index 98c9e1d3c..c40ae2d1e 100644 --- a/libc/sysdeps/linux/common/bits/mman-shared.h +++ b/libc/sysdeps/linux/common/bits/mman-shared.h @@ -40,11 +40,9 @@ __BEGIN_DECLS -#if 0 /* Create a new memory file descriptor. NAME is a name for debugging. FLAGS is a combination of the MFD_* constants. */ int memfd_create (const char *__name, unsigned int __flags) __THROW; -#endif /* Lock pages from ADDR (inclusive) to ADDR + LENGTH (exclusive) into memory. FLAGS is a combination of the MLOCK_* flags above. */ diff --git a/libc/sysdeps/linux/common/bits/msq.h b/libc/sysdeps/linux/common/bits/msq.h index b594cfff2..0cb734263 100644 --- a/libc/sysdeps/linux/common/bits/msq.h +++ b/libc/sysdeps/linux/common/bits/msq.h @@ -37,17 +37,31 @@ typedef unsigned long int msglen_t; struct msqid_ds { struct ipc_perm msg_perm; /* structure describing operation permission */ +#if (__WORDSIZE == 32 && defined(__riscv) && defined(__UCLIBC_USE_TIME64__)) + unsigned long int msg_stime_internal_1; + unsigned long int msg_stime_internal_2; + unsigned long int msg_rtime_internal_1; + unsigned long int msg_rtime_internal_2; + unsigned long int msg_ctime_internal_1; + unsigned long int msg_ctime_internal_2; +#else __time_t msg_stime; /* time of last msgsnd command */ unsigned long int __uclibc_unused1; __time_t msg_rtime; /* time of last msgrcv command */ unsigned long int __uclibc_unused2; __time_t msg_ctime; /* time of last change */ unsigned long int __uclibc_unused3; +#endif unsigned long int __msg_cbytes; /* current number of bytes on queue */ msgqnum_t msg_qnum; /* number of messages currently on queue */ msglen_t msg_qbytes; /* max number of bytes allowed on queue */ __pid_t msg_lspid; /* pid of last msgsnd() */ __pid_t msg_lrpid; /* pid of last msgrcv() */ +#if (__WORDSIZE == 32 && defined(__riscv) && defined(__UCLIBC_USE_TIME64__)) + __time_t msg_stime; /* time of last msgsnd command */ + __time_t msg_rtime; /* time of last msgrcv command */ + __time_t msg_ctime; /* time of last change */ +#endif unsigned long int __uclibc_unused4; unsigned long int __uclibc_unused5; }; diff --git a/libc/sysdeps/linux/common/bits/nan.h b/libc/sysdeps/linux/common/bits/nan.h index 00cb405f1..46cfb613f 100644 --- a/libc/sysdeps/linux/common/bits/nan.h +++ b/libc/sysdeps/linux/common/bits/nan.h @@ -25,7 +25,9 @@ #if __GNUC_PREREQ(3,3) -# define NAN (__builtin_nanf ("")) +# ifndef NAN +# define NAN (__builtin_nanf ("")) +# endif #elif defined __GNUC__ diff --git a/libc/sysdeps/linux/common/bits/sem.h b/libc/sysdeps/linux/common/bits/sem.h index 24a130981..d855494ee 100644 --- a/libc/sysdeps/linux/common/bits/sem.h +++ b/libc/sysdeps/linux/common/bits/sem.h @@ -45,8 +45,8 @@ struct semid_ds #else __time_t sem_otime; /* last semop() time */ #endif -#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__)) || \ - ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__)) && !defined(__UCLIBC_USE_TIME64__)) +#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__) && !defined(__riscv)) || \ + ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__) || defined(__riscv)) && !defined(__UCLIBC_USE_TIME64__)) unsigned long int __uclibc_unused1; #endif #if defined(__UCLIBC_USE_TIME64__) @@ -55,8 +55,8 @@ struct semid_ds #else __time_t sem_ctime; /* last time changed by semctl() */ #endif -#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__)) || \ - ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__)) && !defined(__UCLIBC_USE_TIME64__)) +#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__) && !defined(__riscv)) || \ + ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__) || defined(__riscv)) && !defined(__UCLIBC_USE_TIME64__)) unsigned long int __uclibc_unused2; #endif unsigned long int sem_nsems; /* number of semaphores in set */ diff --git a/libc/sysdeps/linux/common/bits/stab.def b/libc/sysdeps/linux/common/bits/stab.def index 8a2b8f39d..8d16c5c2c 100644 --- a/libc/sysdeps/linux/common/bits/stab.def +++ b/libc/sysdeps/linux/common/bits/stab.def @@ -17,7 +17,7 @@ <http://www.gnu.org/licenses/>. */ /* This contains contribution from Cygnus Support. */ - + /* Global variable. Only the name is significant. To find the address, look in the corresponding external symbol. */ __define_stab (N_GSYM, 0x20, "GSYM") @@ -177,7 +177,7 @@ __define_stab (N_NBLCS, 0xF8, "NBLCS") /* Second symbol entry containing a length-value for the preceding entry. The value is the length. */ __define_stab (N_LENG, 0xfe, "LENG") - + /* The above information, in matrix format. STAB MATRIX diff --git a/libc/sysdeps/linux/common/bits/stat.h b/libc/sysdeps/linux/common/bits/stat.h index 07c09f50a..fc76cc3e7 100644 --- a/libc/sysdeps/linux/common/bits/stat.h +++ b/libc/sysdeps/linux/common/bits/stat.h @@ -61,7 +61,7 @@ struct stat #else __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ #endif -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -107,7 +107,7 @@ struct stat64 __blksize_t st_blksize; /* Optimal block size for I/O. */ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the diff --git a/libc/sysdeps/linux/common/clock_adjtime.c b/libc/sysdeps/linux/common/clock_adjtime.c index 53f64e9d5..ada256ccd 100644 --- a/libc/sysdeps/linux/common/clock_adjtime.c +++ b/libc/sysdeps/linux/common/clock_adjtime.c @@ -15,5 +15,5 @@ _syscall2_64(int, clock_adjtime, clockid_t, clock_id, struct timex*, ntx) #elif defined(__NR_clock_adjtime) _syscall2(int, clock_adjtime, clockid_t, clock_id, struct timex*, ntx) #else -#error "clock_adjtime syscall is not defined!" +#warning "clock_adjtime syscall is not defined!" #endif diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c index 4d787b9b7..b924d860b 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -11,10 +11,14 @@ #include <sys/syscall.h> #include <time.h> +#ifdef __VDSO_SUPPORT__ +#include "ldso.h" +#endif + #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) #include "internal/time64_helpers.h" -int clock_gettime(clockid_t clock_id, struct timespec *tp) +int __libc_clock_gettime(clockid_t clock_id, struct timespec *tp) { struct __ts64_struct __ts64; int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64); @@ -26,11 +30,14 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp) return __ret; } #elif defined(__NR_clock_gettime) -_syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) +int __libc_clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + return INLINE_SYSCALL(clock_gettime, 2, clock_id, tp); +} #else # include <sys/time.h> -int clock_gettime(clockid_t clock_id, struct timespec* tp) +int __libc_clock_gettime(clockid_t clock_id, struct timespec* tp) { struct timeval tv; int retval = -1; @@ -53,3 +60,12 @@ int clock_gettime(clockid_t clock_id, struct timespec* tp) return retval; } #endif + +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ +#if defined(__VDSO_SUPPORT__) && defined(ARCH_VDSO_CLOCK_GETTIME) + return ARCH_VDSO_CLOCK_GETTIME(clock_id, tp); +#else + return __libc_clock_gettime(clock_id, tp); +#endif +} diff --git a/libc/sysdeps/linux/common/fstat64.c b/libc/sysdeps/linux/common/fstat64.c index 359c22af6..121b21fc8 100644 --- a/libc/sysdeps/linux/common/fstat64.c +++ b/libc/sysdeps/linux/common/fstat64.c @@ -8,8 +8,9 @@ #include <_lfs_64.h> #include <sys/syscall.h> +#include <linux/version.h> -#if defined(__NR_fstat64) && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_fstat64) && (!defined(__UCLIBC_USE_TIME64__) || LINUX_VERSION_CODE <= KERNEL_VERSION(5,1,0)) # include <unistd.h> # include <sys/stat.h> # include "xstatconv.h" diff --git a/libc/sysdeps/linux/common/fstatat64.c b/libc/sysdeps/linux/common/fstatat64.c index 16dbf9215..739e84081 100644 --- a/libc/sysdeps/linux/common/fstatat64.c +++ b/libc/sysdeps/linux/common/fstatat64.c @@ -9,6 +9,7 @@ #include <_lfs_64.h> #include <bits/wordsize.h> #include <sys/syscall.h> +#include <linux/version.h> #if defined __mips__ # include <sgidefs.h> @@ -23,7 +24,7 @@ # define __NR_fstatat64 __NR_newfstatat #endif -#if defined(__NR_fstatat64) && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_fstatat64) && (!defined(__UCLIBC_USE_TIME64__) || LINUX_VERSION_CODE <= KERNEL_VERSION(5,1,0)) # include <sys/stat.h> # include "xstatconv.h" int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) diff --git a/libc/sysdeps/linux/common/futimens.c b/libc/sysdeps/linux/common/futimens.c index 03e58f4b5..2f3d72420 100644 --- a/libc/sysdeps/linux/common/futimens.c +++ b/libc/sysdeps/linux/common/futimens.c @@ -8,7 +8,7 @@ #include <sys/syscall.h> #include <time.h> -#ifdef __NR_utimensat +#if defined(__NR_utimensat) || defined(__NR_utimensat_time64) /* To avoid superfluous warnings about passing NULL to the non-null annotated * 2nd param "__path" below, we bypass inclusion of sys/stat.h and use * a non annotated, local decl. diff --git a/libc/sysdeps/linux/common/futimesat.c b/libc/sysdeps/linux/common/futimesat.c index fd19fea7c..bf36550dd 100644 --- a/libc/sysdeps/linux/common/futimesat.c +++ b/libc/sysdeps/linux/common/futimesat.c @@ -7,6 +7,7 @@ */ #include <sys/syscall.h> +#include <sys/stat.h> #include <sys/time.h> #ifdef __NR_futimesat diff --git a/libc/sysdeps/linux/common/getentropy.c b/libc/sysdeps/linux/common/getentropy.c new file mode 100644 index 000000000..d255310b6 --- /dev/null +++ b/libc/sysdeps/linux/common/getentropy.c @@ -0,0 +1,46 @@ +/* + * getentropy() by wrapping getrandom(), for µClibc-ng + * + * © 2025 mirabilos Ⓕ CC0 or MirBSD or GNU LGPLv2 + * + * Note: may be a thread cancellation point, unlike the + * implementations in glibc and musl libc. Should this + * ever become a concern, it will need patching. + */ + +#define _DEFAULT_SOURCE +#include <errno.h> +#include <unistd.h> +#include <sys/random.h> +#include <sys/syscall.h> + +#ifdef __NR_getrandom +int +getentropy(void *__buf, size_t __len) +{ + ssize_t n; + + if (__len > 256U) { + errno = EIO; + return (-1); + } + + again: + if ((n = getrandom(__buf, __len, 0)) == -1) + switch (errno) { + case EAGAIN: /* should not happen but better safe than sorry */ + case EINTR: + goto again; + default: + errno = EIO; + /* FALLTHROUGH */ + case EFAULT: + case ENOSYS: + return (-1); + } + if ((size_t)n != __len) + /* also shouldn’t happen (safety net) */ + goto again; + return (0); +} +#endif diff --git a/libc/sysdeps/linux/common/getrandom.c b/libc/sysdeps/linux/common/getrandom.c index bb9841463..1db1663b9 100644 --- a/libc/sysdeps/linux/common/getrandom.c +++ b/libc/sysdeps/linux/common/getrandom.c @@ -8,6 +8,7 @@ #include <sys/syscall.h> #include <sys/random.h> + #ifdef __NR_getrandom -_syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags) +_syscall3(ssize_t, getrandom, void *, buf, size_t, buflen, unsigned int, flags) #endif diff --git a/libc/sysdeps/linux/common/gettimeofday.c b/libc/sysdeps/linux/common/gettimeofday.c index ed18b2be5..9b29fe5a0 100755 --- a/libc/sysdeps/linux/common/gettimeofday.c +++ b/libc/sysdeps/linux/common/gettimeofday.c @@ -14,30 +14,18 @@ #include "ldso.h" #endif -#ifdef __VDSO_SUPPORT__ -typedef int (*gettimeofday_func)(struct timeval * tv, __timezone_ptr_t tz); -#endif - int gettimeofday(struct timeval * tv, __timezone_ptr_t tz) { - - #ifdef __VDSO_SUPPORT__ - if ( _dl__vdso_gettimeofday != 0 ){ - gettimeofday_func func= _dl__vdso_gettimeofday; - return func( tv, tz ); - - }else{ - _syscall2_body(int, gettimeofday, struct timeval *, tv, __timezone_ptr_t, tz) - } - #else - if (!tv) - return 0; - - struct timespec __ts; - int __ret = clock_gettime(CLOCK_REALTIME, &__ts); - tv->tv_sec = __ts.tv_sec; - tv->tv_usec = (suseconds_t)__ts.tv_nsec / 1000; - return __ret; - #endif + if (!tv) + return 0; +#if defined(__VDSO_SUPPORT__) && defined(ARCH_VDSO_GETTIMEOFDAY) + return ARCH_VDSO_GETTIMEOFDAY(tv, tz); +#else + struct timespec __ts; + int __ret = clock_gettime(CLOCK_REALTIME, &__ts); + tv->tv_sec = __ts.tv_sec; + tv->tv_usec = (suseconds_t)__ts.tv_nsec / 1000; + return __ret; +#endif } diff --git a/libc/sysdeps/linux/common/lseek.c b/libc/sysdeps/linux/common/lseek.c index 80d69318a..0fc99efae 100644 --- a/libc/sysdeps/linux/common/lseek.c +++ b/libc/sysdeps/linux/common/lseek.c @@ -40,6 +40,8 @@ off_t __NC(lseek)(int fd, off_t offset attribute_unused, int whence) case SEEK_SET: case SEEK_CUR: case SEEK_END: + case SEEK_DATA: + case SEEK_HOLE: break; default: __set_errno(EINVAL); diff --git a/libc/sysdeps/linux/common/memfd_create.c b/libc/sysdeps/linux/common/memfd_create.c new file mode 100644 index 000000000..7165f3278 --- /dev/null +++ b/libc/sysdeps/linux/common/memfd_create.c @@ -0,0 +1,13 @@ +/* + * memfd_create() for uClibc-ng + * + * Copyright (C) 2024 Waldemar Brodkorb <wbx@uclibc-ng.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#include <sys/syscall.h> +#include <sys/mman.h> +#if defined(__NR_memfd_create) +_syscall2(int, memfd_create, const char *, name, unsigned int, flags) +#endif diff --git a/libc/sysdeps/linux/common/not-cancel.h b/libc/sysdeps/linux/common/not-cancel.h index 9d1588494..426edcc46 100644 --- a/libc/sysdeps/linux/common/not-cancel.h +++ b/libc/sysdeps/linux/common/not-cancel.h @@ -19,6 +19,7 @@ #include <sys/types.h> #include <sysdep.h> +#include <time.h> #ifdef NOT_IN_libc @@ -113,9 +114,10 @@ extern __typeof(pause) __pause_nocancel; #ifdef __NR_nanosleep # define nanosleep_not_cancel(requested_time, remaining) \ INLINE_SYSCALL (nanosleep, 2, requested_time, remaining) -/*#else +#else +extern int __nanosleep_nocancel (const struct timespec *requested_time, struct timespec *remaining); # define nanosleep_not_cancel(requested_time, remaining) \ - __nanosleep_nocancel (requested_time, remaining)*/ + __nanosleep_nocancel (requested_time, remaining) #endif #if 0 diff --git a/libc/sysdeps/linux/common/process_vm_readv.c b/libc/sysdeps/linux/common/process_vm_readv.c new file mode 100644 index 000000000..b69c1c97a --- /dev/null +++ b/libc/sysdeps/linux/common/process_vm_readv.c @@ -0,0 +1,32 @@ +/* process_vm_readv - Linux specific syscall. + Copyright (C) 2020-2024 Free Software Foundation, Inc. + + 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 <sys/uio.h> +#include <sys/syscall.h> +#include <unistd.h> + +#ifdef __NR_process_vm_readv +ssize_t +process_vm_readv (pid_t pid, const struct iovec *local_iov, + unsigned long int liovcnt, + const struct iovec *remote_iov, + unsigned long int riovcnt, unsigned long int flags) +{ + return INLINE_SYSCALL (process_vm_readv, 6, pid, local_iov, + liovcnt, remote_iov, riovcnt, flags); +} +#endif diff --git a/libc/sysdeps/linux/common/process_vm_writev.c b/libc/sysdeps/linux/common/process_vm_writev.c new file mode 100644 index 000000000..e22817a8d --- /dev/null +++ b/libc/sysdeps/linux/common/process_vm_writev.c @@ -0,0 +1,32 @@ +/* process_vm_writev - Linux specific syscall. + Copyright (C) 2020-2024 Free Software Foundation, Inc. + + 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 <sys/uio.h> +#include <sys/syscall.h> +#include <unistd.h> + +#ifdef __NR_process_vm_writev +ssize_t +process_vm_writev (pid_t pid, const struct iovec *local_iov, + unsigned long int liovcnt, + const struct iovec *remote_iov, + unsigned long int riovcnt, unsigned long int flags) +{ + return INLINE_SYSCALL (process_vm_writev, 6, pid, local_iov, + liovcnt, remote_iov, riovcnt, flags); +} +#endif diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c index 7a446a589..f9d16d6c8 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -34,7 +34,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask) { -#ifdef __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) /* The Linux kernel can in some situations update the timeout value. * We do not want that so use a local variable. */ diff --git a/libc/sysdeps/linux/common/sys/epoll.h b/libc/sysdeps/linux/common/sys/epoll.h index 5551bed0d..5138d77a9 100644 --- a/libc/sysdeps/linux/common/sys/epoll.h +++ b/libc/sysdeps/linux/common/sys/epoll.h @@ -19,6 +19,7 @@ #define _SYS_EPOLL_H 1 #include <stdint.h> +#include <sys/ioctl.h> #include <sys/types.h> /* Get __sigset_t. */ @@ -87,6 +88,19 @@ struct epoll_event epoll_data_t data; /* User data variable */ } __EPOLL_PACKED; +struct epoll_params +{ + uint32_t busy_poll_usecs; + uint16_t busy_poll_budget; + uint8_t prefer_busy_poll; + + /* pad the struct to a multiple of 64bits */ + uint8_t __pad; +}; + +#define EPOLL_IOC_TYPE 0x8A +#define EPIOCSPARAMS _IOW(EPOLL_IOC_TYPE, 0x01, struct epoll_params) +#define EPIOCGPARAMS _IOR(EPOLL_IOC_TYPE, 0x02, struct epoll_params) __BEGIN_DECLS diff --git a/libc/sysdeps/linux/common/sys/random.h b/libc/sysdeps/linux/common/sys/random.h index 3d12744ad..c3d9cf575 100644 --- a/libc/sysdeps/linux/common/sys/random.h +++ b/libc/sysdeps/linux/common/sys/random.h @@ -4,12 +4,20 @@ #ifndef _SYS_RANDOM_H #define _SYS_RANDOM_H 1 + #include <features.h> #include <stddef.h> __BEGIN_DECLS -#if defined __UCLIBC_LINUX_SPECIFIC__ && defined __USE_GNU +#include <bits/types.h> + +#ifndef __ssize_t_defined +typedef __ssize_t ssize_t; +# define __ssize_t_defined +#endif + +#if defined __UCLIBC_LINUX_SPECIFIC__ # if 0 /*def __ASSUME_GETRANDOM_SYSCALL */ # include <linux/random.h> # else @@ -20,13 +28,21 @@ __BEGIN_DECLS * * GRND_NONBLOCK Don't block and return EAGAIN instead * GRND_RANDOM Use the /dev/random pool instead of /dev/urandom + * GRND_INSECURE Write random data that may not be cryptographically secure. */ # define GRND_NONBLOCK 0x0001 # define GRND_RANDOM 0x0002 +# define GRND_INSECURE 0x0004 # endif -/* FIXME: aren't there a couple of __restrict and const missing ? */ -extern int getrandom(void *__buf, size_t count, unsigned int flags) +extern ssize_t getrandom(void *__buf, size_t count, unsigned int flags) __nonnull ((1)) __wur; + +/* OpenBSD-compatible access to random bytes. + May be a cancellation point here, unlike in glibc/musl. */ +# ifndef __getentropy_defined +extern int getentropy(void *__buf, size_t __len) __nonnull ((1)) __wur; +# define __getentropy_defined +# endif #endif __END_DECLS diff --git a/libc/sysdeps/linux/common/utime.c b/libc/sysdeps/linux/common/utime.c index e4ac0b269..c716388e8 100644 --- a/libc/sysdeps/linux/common/utime.c +++ b/libc/sysdeps/linux/common/utime.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <utime.h> -#if defined __NR_utimensat && !defined __NR_utime +#if (defined(__NR_utimensat) || defined(__NR_utimensat_time64)) && !defined __NR_utime # include <fcntl.h> # include <stddef.h> @@ -51,7 +51,7 @@ int utime(const char *file, const struct utimbuf *times) } #endif -#if (defined __NR_utimensat && !defined __NR_utime) || \ +#if ((defined(__NR_utimensat) || defined(__NR_utimensat_time64)) && !defined __NR_utime) || \ defined __NR_utime || defined __NR_utimes libc_hidden_def(utime) #endif diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index fa6f90e55..5816c7890 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -8,6 +8,7 @@ #include <sys/syscall.h> #include <sys/stat.h> +#include <stdint.h> #if defined(__UCLIBC_USE_TIME64__) #include "internal/time64_helpers.h" @@ -28,7 +29,7 @@ int utimensat(int fd, const char *path, const struct timespec times[2], int flag } }; - return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__times64 : 0, flags); + return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? (uintptr_t) &__times64 : 0, flags); } #else _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) diff --git a/libc/sysdeps/linux/common/utimes.c b/libc/sysdeps/linux/common/utimes.c index e6fc578f3..c471a9b89 100644 --- a/libc/sysdeps/linux/common/utimes.c +++ b/libc/sysdeps/linux/common/utimes.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <sys/time.h> -#if defined __NR_utimensat && !defined __NR_utimes +#if (defined (__NR_utimensat) || defined(__NR_utimensat_time64)) && (!defined __NR_utimes || defined(__UCLIBC_USE_TIME64__)) # include <fcntl.h> # include <stddef.h> int utimes(const char *file, const struct timeval tvp[2]) @@ -50,6 +50,6 @@ int utimes(const char *file, const struct timeval tvp[2]) } #endif -#if defined __NR_utimensat || defined __NR_utimes || defined __NR_utime +#if (((defined __NR_utimensat || defined __NR_utimensat_time64) && (!defined __NR_utimes || defined __UCLIBC_USE_TIME64__))) || defined __NR_utimes || defined __NR_utime libc_hidden_def(utimes) #endif diff --git a/libc/sysdeps/linux/common/wait4.c b/libc/sysdeps/linux/common/wait4.c index cd042d5e7..486ffaab8 100644 --- a/libc/sysdeps/linux/common/wait4.c +++ b/libc/sysdeps/linux/common/wait4.c @@ -10,6 +10,7 @@ #include <sys/wait.h> #include <sys/resource.h> +#if defined(__NR_wait4) # define __NR___syscall_wait4 __NR_wait4 static __always_inline _syscall4(int, __syscall_wait4, __kernel_pid_t, pid, int *, status, int, opts, struct rusage *, rusage) @@ -32,6 +33,59 @@ pid_t __wait4_nocancel(pid_t pid, int *status, int opts, struct rusage *rusage) return __syscall_wait4(pid, status, opts, rusage); #endif } + +#else +pid_t __wait4_nocancel(pid_t pid, int *status, int opts, struct rusage *rusage) +{ + idtype_t type; + int __res; + siginfo_t info; + + info.si_pid = 0; + + if (pid < -1) { + type = P_PGID; + pid = -pid; + } else if (pid == -1) { + type = P_ALL; + } else if (pid == 0) { + type = P_PGID; + } else { + type = P_PID; + } + + __res = INLINE_SYSCALL(waitid, 5, type, pid, &info, opts|WEXITED, rusage); + + if ( __res < 0 ) + return __res; + + if (info.si_pid && status) { + int sw = 0; + switch (info.si_code) { + case CLD_CONTINUED: + sw = 0xffff; + break; + case CLD_DUMPED: + sw = (info.si_status & 0x7f) | 0x80; + break; + case CLD_EXITED: + sw = (info.si_status & 0xff) << 8; + break; + case CLD_KILLED: + sw = info.si_status & 0x7f; + break; + case CLD_STOPPED: + case CLD_TRAPPED: + sw = (info.si_status << 8) + 0x7f; + break; + } + *status = sw; + } + + return info.si_pid; +} +#endif + #ifdef __USE_BSD strong_alias(__wait4_nocancel,wait4) #endif diff --git a/libc/sysdeps/linux/cris/bits/fcntl.h b/libc/sysdeps/linux/cris/bits/fcntl.h index e9bc90ea9..e1d4ee1a6 100644 --- a/libc/sysdeps/linux/cris/bits/fcntl.h +++ b/libc/sysdeps/linux/cris/bits/fcntl.h @@ -245,3 +245,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/csky/bits/fcntl.h b/libc/sysdeps/linux/csky/bits/fcntl.h index b36f41569..25f4491ba 100644 --- a/libc/sysdeps/linux/csky/bits/fcntl.h +++ b/libc/sysdeps/linux/csky/bits/fcntl.h @@ -232,3 +232,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/csky/bits/fenv.h b/libc/sysdeps/linux/csky/bits/fenv.h index 3359e1f8e..1428f385a 100644 --- a/libc/sysdeps/linux/csky/bits/fenv.h +++ b/libc/sysdeps/linux/csky/bits/fenv.h @@ -1,65 +1,108 @@ -/* - * Copyright (C) 2017 Hangzhou C-SKY Microsystems co.,ltd. - * - * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB - * in this tarball. - */ +/* Floating point environment. C-SKY version. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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 bits representing the exception. We use the bit positions of - the appropriate bits in the FPSR Accrued Exception Byte. */ +#ifdef __csky_hard_float__ +/* Define bits representing the exception. We use the bit positions + of the appropriate bits in the FPU control word. */ enum { - FE_INEXACT = 1 << 3, -#define FE_INEXACT FE_INEXACT - FE_DIVBYZERO = 1 << 4, -#define FE_DIVBYZERO FE_DIVBYZERO - FE_UNDERFLOW = 1 << 5, -#define FE_UNDERFLOW FE_UNDERFLOW - FE_OVERFLOW = 1 << 6, -#define FE_OVERFLOW FE_OVERFLOW - FE_INVALID = 1 << 7 -#define FE_INVALID FE_INVALID + FE_INVALID = +#define FE_INVALID 0x01 + FE_INVALID, + FE_DIVBYZERO = +#define FE_DIVBYZERO 0x02 + FE_DIVBYZERO, + FE_OVERFLOW = +#define FE_OVERFLOW 0x04 + FE_OVERFLOW, + FE_UNDERFLOW = +#define FE_UNDERFLOW 0x08 + FE_UNDERFLOW, + FE_INEXACT = +#define FE_INEXACT 0x10 + FE_INEXACT, + __FE_DENORMAL = 0x20 }; #define FE_ALL_EXCEPT \ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) -/* The csky FPU supports all of the four defined rounding modes. We use - the bit positions in the FPCR Mode Control Byte as the values for the - appropriate macros. */ +/* The C-SKY FPU supports all of the four defined rounding modes. We + use again the bit positions in the FPU control word as the values + for the appropriate macros. */ +enum + { + FE_TONEAREST = +#define FE_TONEAREST (0x0 << 24) + FE_TONEAREST, + FE_TOWARDZERO = +#define FE_TOWARDZERO (0x1 << 24) + FE_TOWARDZERO, + FE_UPWARD = +#define FE_UPWARD (0x2 << 24) + FE_UPWARD, + FE_DOWNWARD = +#define FE_DOWNWARD (0x3 << 24) + FE_DOWNWARD, + __FE_ROUND_MASK = (0x3 << 24) + }; + +#else + +/* In the soft-float case, only rounding to nearest is supported, with + no exceptions. */ + enum { - FE_TONEAREST = 0, -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = 1 << 4, -#define FE_TOWARDZERO FE_TOWARDZERO - FE_DOWNWARD = 2 << 4, -#define FE_DOWNWARD FE_DOWNWARD - FE_UPWARD = 3 << 4 -#define FE_UPWARD FE_UPWARD + __FE_UNDEFINED = -1, + + FE_TONEAREST = +# define FE_TONEAREST 0x0 + FE_TONEAREST }; +# define FE_ALL_EXCEPT 0 + +#endif + /* Type representing exception flags. */ typedef unsigned int fexcept_t; -/* Type representing floating-point environment. This structure - corresponds to the layout of the block written by `fmovem'. */ +/* Type representing floating-point environment. */ typedef struct - { - unsigned int __control_register; - unsigned int __status_register; - unsigned int __instruction_address; - } -fenv_t; +{ + unsigned int __fpcr; + unsigned int __fpsr; +} fenv_t; /* If the default argument is used we use this value. */ -#define FE_DFL_ENV ((__const fenv_t *) -1) +#define FE_DFL_ENV ((const fenv_t *) -1) -#ifdef __USE_GNU +#if defined __USE_GNU && defined __csky_hard_float__ /* Floating-point environment where none of the exceptions are masked. */ -# define FE_NOMASK_ENV ((__const fenv_t *) -2) +# define FE_NOMASK_ENV ((const fenv_t *) -2) #endif + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h b/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h index 3f5dab80c..1b866cb90 100644 --- a/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h +++ b/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h @@ -17,9 +17,6 @@ /* can your target use syscall6() for mmap ? */ #undef __UCLIBC_MMAP_HAS_6_ARGS__ -/* does your target use statx */ -#define __UCLIBC_HAVE_STATX__ - #ifdef __CSKYABIV2__ #undef __UCLIBC_SYSCALL_ALIGN_64BIT__ #else diff --git a/libc/sysdeps/linux/csky/fpu_control.h b/libc/sysdeps/linux/csky/fpu_control.h new file mode 100644 index 000000000..a2d615554 --- /dev/null +++ b/libc/sysdeps/linux/csky/fpu_control.h @@ -0,0 +1,147 @@ +/* FPU control word bits. C-SKY version. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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 _FPU_CONTROL_H +#define _FPU_CONTROL_H + +/* C-SKY FPU floating point control register bits. + + 31-28 -> Reserved (read as 0, write with 0). + 27 -> 0: Flush denormalized results to zero. + 1: Flush denormalized results to signed minimal normal number. + 26 -> Reserved (read as 0, write with 0). + 25-24 -> Rounding control. + 23-6 -> Reserved (read as 0, write with 0). + 5 -> Enable exception for input denormalized exception. + 4 -> Enable exception for inexact exception. + 3 -> Enable exception for underflow exception. + 2 -> Enable exception for overflow exception. + 1 -> Enable exception for division by zero exception. + 0 -> Enable exception for invalid operation exception. + + Rounding Control: + 00 - Rounding to nearest (RN). + 01 - Rounding toward zero (RZ). + 10 - Rounding (up) toward plus infinity (RP). + 11 - Rounding (down)toward minus infinity (RM). + + C-SKY FPU floating point exception status register bits. + + 15 -> Accumulate bit for any exception. + 14 -> Reserved (read as 0, write with 0). + 13 -> Cause bit for input denormalized exception. + 12 -> Cause bit for inexact exception. + 11 -> Cause bit for underflow exception. + 10 -> Cause bit for overflow exception. + 9 -> Cause bit for division by zero exception. + 8 -> Cause bit for invalid operation exception. + 7 -> Flag bit for any exception. + 6 -> Reserved (read as 0, write with 0). + 5 -> Flag exception for input denormalized exception. + 4 -> Flag exception for inexact exception. + 3 -> Flag exception for underflow exception. + 2 -> Flag exception for overflow exception. + 1 -> Flag exception for division by zero exception. + 0 -> Flag exception for invalid operation exception. */ + +#include <features.h> + +#ifdef __csky_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) +# define _FPU_GETFPSR(cw) (cw) = 0 +# define _FPU_SETFPSR(cw) (void) (cw) +extern fpu_control_t __fpu_control; + +#else /* __csky_soft_float__ */ + +/* Masking of interrupts. */ +# define _FPU_MASK_IDE (1 << 5) /* Input denormalized exception. */ +# define _FPU_MASK_IXE (1 << 4) /* Inexact exception. */ +# define _FPU_MASK_UFE (1 << 3) /* Underflow exception. */ +# define _FPU_MASK_OFE (1 << 2) /* Overflow exception. */ +# define _FPU_MASK_DZE (1 << 1) /* Division by zero exception. */ +# define _FPU_MASK_IOE (1 << 0) /* Invalid operation exception. */ + +# define _FPU_MASK_FEA (1 << 15) /* Case for any exception. */ +# define _FPU_MASK_FEC (1 << 7) /* Flag for any exception. */ + +/* Flush denormalized numbers to zero. */ +# define _FPU_FLUSH_TZ 0x8000000 + +/* Rounding control. */ +# define _FPU_RC_NEAREST (0x0 << 24) /* RECOMMENDED. */ +# define _FPU_RC_ZERO (0x1 << 24) +# define _FPU_RC_UP (0x2 << 24) +# define _FPU_RC_DOWN (0x3 << 24) + +# define _FPU_RESERVED 0xf460ffc0 /* Reserved bits in cw. */ +# define _FPU_FPSR_RESERVED 0xffff4040 + +/* The fdlibm code requires strict IEEE double precision arithmetic, + and no interrupts for exceptions, rounding to nearest. */ + +# define _FPU_DEFAULT 0x00000000 +# define _FPU_FPSR_DEFAULT 0x00000000 + +/* IEEE: same as above, but exceptions. */ +# define _FPU_FPCR_IEEE 0x0000001F +# define _FPU_FPSR_IEEE 0x00000000 + +/* Type of the control word. */ +typedef unsigned int fpu_control_t; + +/* Macros for accessing the hardware control word. */ +# if (__CSKY__ == 2) +# define _FPU_GETCW(cw) __asm__ volatile ("mfcr %0, cr<1, 2>" : "=a" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("mtcr %0, cr<1, 2>" : : "a" (cw)) +# define _FPU_GETFPSR(cw) __asm__ volatile ("mfcr %0, cr<2, 2>" : "=a" (cw)) +# define _FPU_SETFPSR(cw) __asm__ volatile ("mtcr %0, cr<2, 2>" : : "a" (cw)) +# else +# define _FPU_GETCW(cw) __asm__ volatile ("1: cprcr %0, cpcr2 \n" \ + " btsti %0, 31 \n" \ + " bt 1b \n" \ + " cprcr %0, cpcr1\n" : "=b" (cw)) + +# define _FPU_SETCW(cw) __asm__ volatile ("1: cprcr r7, cpcr2 \n" \ + " btsti r7, 31 \n" \ + " bt 1b \n" \ + " cpwcr %0, cpcr1 \n" \ + : : "b" (cw) : "r7") + +# define _FPU_GETFPSR(cw) __asm__ volatile ("1: cprcr %0, cpcr2 \n" \ + " btsti %0, 31 \n" \ + " bt 1b \n" \ + " cprcr %0, cpcr4\n" : "=b" (cw)) + +# define _FPU_SETFPSR(cw) __asm__ volatile ("1: cprcr r7, cpcr2 \n" \ + " btsti r7, 31 \n" \ + " bt 1b \n" \ + " cpwcr %0, cpcr4 \n" \ + : : "b" (cw) : "r7") +# endif /* __CSKY__ != 2 */ + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif /* !__csky_soft_float__ */ + +#endif /* fpu_control.h */ diff --git a/libc/sysdeps/linux/frv/bits/fcntl.h b/libc/sysdeps/linux/frv/bits/fcntl.h index 02c8ac310..81a1bcd99 100644 --- a/libc/sysdeps/linux/frv/bits/fcntl.h +++ b/libc/sysdeps/linux/frv/bits/fcntl.h @@ -226,3 +226,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/frv/bits/stat.h b/libc/sysdeps/linux/frv/bits/stat.h index 381d207f2..18321c080 100644 --- a/libc/sysdeps/linux/frv/bits/stat.h +++ b/libc/sysdeps/linux/frv/bits/stat.h @@ -70,7 +70,7 @@ struct stat __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ #endif -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -117,7 +117,7 @@ struct stat64 __blksize_t st_blksize; /* Optimal block size for I/O. */ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the diff --git a/libc/sysdeps/linux/h8300/bits/fcntl.h b/libc/sysdeps/linux/h8300/bits/fcntl.h index 2062f7cda..7cbe04e15 100644 --- a/libc/sysdeps/linux/h8300/bits/fcntl.h +++ b/libc/sysdeps/linux/h8300/bits/fcntl.h @@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/hppa/bits/fcntl.h b/libc/sysdeps/linux/hppa/bits/fcntl.h index 4ce76ce5f..bcd6618b2 100644 --- a/libc/sysdeps/linux/hppa/bits/fcntl.h +++ b/libc/sysdeps/linux/hppa/bits/fcntl.h @@ -234,3 +234,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/i386/bits/fcntl.h b/libc/sysdeps/linux/i386/bits/fcntl.h index f3c08bbe5..5caf66114 100644 --- a/libc/sysdeps/linux/i386/bits/fcntl.h +++ b/libc/sysdeps/linux/i386/bits/fcntl.h @@ -245,3 +245,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/i386/sigaction.c b/libc/sysdeps/linux/i386/sigaction.c index cf6daa787..515ef99f2 100644 --- a/libc/sysdeps/linux/i386/sigaction.c +++ b/libc/sysdeps/linux/i386/sigaction.c @@ -31,15 +31,16 @@ extern void restore_rt(void) __asm__ ("__restore_rt") attribute_hidden; extern void restore(void) __asm__ ("__restore") attribute_hidden; -/* If ACT is not NULL, change the action for SIG to *ACT. +/* If ACT is not NULL, change mask, handler and flags for SIG to ACT's If OACT is not NULL, put the old action for SIG in *OACT. */ int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { struct sigaction kact; if (act) { - memcpy(&kact, act, sizeof(kact)); - kact.sa_flags |= SA_RESTORER; + memcpy(&kact.sa_mask, &act->sa_mask, sizeof(sigset_t)); + kact.sa_handler = act->sa_handler; + kact.sa_flags = act->sa_flags; kact.sa_restorer = (act->sa_flags & SA_SIGINFO) ? &restore_rt : &restore; act = &kact; } diff --git a/libc/sysdeps/linux/ia64/bits/fcntl.h b/libc/sysdeps/linux/ia64/bits/fcntl.h index a20f44ff7..53263c3d3 100644 --- a/libc/sysdeps/linux/ia64/bits/fcntl.h +++ b/libc/sysdeps/linux/ia64/bits/fcntl.h @@ -238,3 +238,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/ia64/bits/stat.h b/libc/sysdeps/linux/ia64/bits/stat.h index 6723166e7..2b70b8cf8 100644 --- a/libc/sysdeps/linux/ia64/bits/stat.h +++ b/libc/sysdeps/linux/ia64/bits/stat.h @@ -38,7 +38,7 @@ struct stat int pad0; __dev_t st_rdev; /* Device number, if device. */ __off_t st_size; /* Size of file, in bytes. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -77,7 +77,7 @@ struct stat64 int pad0; __dev_t st_rdev; /* Device number, if device. */ __off_t st_size; /* Size of file, in bytes. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the diff --git a/libc/sysdeps/linux/kvx/bits/fcntl.h b/libc/sysdeps/linux/kvx/bits/fcntl.h index ea0c59d09..79cd3f14e 100644 --- a/libc/sysdeps/linux/kvx/bits/fcntl.h +++ b/libc/sysdeps/linux/kvx/bits/fcntl.h @@ -227,3 +227,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS + +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/kvx/bits/shm.h b/libc/sysdeps/linux/kvx/bits/shm.h new file mode 100644 index 000000000..bfb603499 --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/shm.h @@ -0,0 +1,87 @@ +/* + * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB + * in this tarball. + */ + +#ifndef _SYS_SHM_H +# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead." +#endif + +#include <bits/types.h> + +/* Permission flag for shmget. */ +#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */ +#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */ + +/* Flags for `shmat'. */ +#define SHM_RDONLY 010000 /* attach read-only else read-write */ +#define SHM_RND 020000 /* round attach address to SHMLBA */ +#define SHM_REMAP 040000 /* take-over region on attach */ + +/* Commands for `shmctl'. */ +#define SHM_LOCK 11 /* lock segment (root only) */ +#define SHM_UNLOCK 12 /* unlock segment (root only) */ + +__BEGIN_DECLS + +/* Segment low boundary address multiple. */ +#define SHMLBA (__getpagesize () << 2) +extern int __getpagesize (void) __THROW __attribute__ ((__const__)); + + +/* Type to count number of attaches. */ +typedef unsigned long int shmatt_t; + +/* Data structure describing a set of semaphores. */ +struct shmid_ds + { + struct ipc_perm shm_perm; /* operation permission struct */ + size_t shm_segsz; /* size of segment in bytes */ + __time_t shm_atime; /* time of last shmat() */ + __time_t shm_dtime; /* time of last shmdt() */ + __time_t shm_ctime; /* time of last change by shmctl() */ + __pid_t shm_cpid; /* pid of creator */ + __pid_t shm_lpid; /* pid of last shmop */ + shmatt_t shm_nattch; /* number of current attaches */ + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; + }; + +#ifdef __USE_MISC + +/* ipcs ctl commands */ +# define SHM_STAT 13 +# define SHM_INFO 14 + +/* shm_mode upper byte flags */ +# define SHM_DEST 01000 /* segment will be destroyed on last detach */ +# define SHM_LOCKED 02000 /* segment will not be swapped */ +# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */ +# define SHM_NORESERVE 010000 /* don't check for reservations */ + +struct shminfo + { + unsigned long int shmmax; + unsigned long int shmmin; + unsigned long int shmmni; + unsigned long int shmseg; + unsigned long int shmall; + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; + unsigned long int __uclibc_unused3; + unsigned long int __uclibc_unused4; + }; + +struct shm_info + { + int used_ids; + unsigned long int shm_tot; /* total allocated shm */ + unsigned long int shm_rss; /* total resident shm */ + unsigned long int shm_swp; /* total swapped shm */ + unsigned long int swap_attempts; + unsigned long int swap_successes; + }; + +#endif /* __USE_MISC */ + +__END_DECLS diff --git a/libc/sysdeps/linux/lm32/bits/fcntl.h b/libc/sysdeps/linux/lm32/bits/fcntl.h index 0bfea6e7a..049c7fd83 100644 --- a/libc/sysdeps/linux/lm32/bits/fcntl.h +++ b/libc/sysdeps/linux/lm32/bits/fcntl.h @@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/m68k/bits/fcntl.h b/libc/sysdeps/linux/m68k/bits/fcntl.h index 5a56c8781..92c0964d9 100644 --- a/libc/sysdeps/linux/m68k/bits/fcntl.h +++ b/libc/sysdeps/linux/m68k/bits/fcntl.h @@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/m68k/bits/fenv.h b/libc/sysdeps/linux/m68k/bits/fenv.h index b07f0ab51..37c5fe829 100644 --- a/libc/sysdeps/linux/m68k/bits/fenv.h +++ b/libc/sysdeps/linux/m68k/bits/fenv.h @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* Copyright (C) 1997-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -12,31 +11,38 @@ 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 - <http://www.gnu.org/licenses/>. */ + 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 +#if defined __HAVE_68881__ || defined __HAVE_FPU__ || defined __mcffpu__ + /* Define bits representing the exception. We use the bit positions of the appropriate bits in the FPSR Accrued Exception Byte. */ enum { - FE_INEXACT = 1 << 3, -#define FE_INEXACT FE_INEXACT - FE_DIVBYZERO = 1 << 4, -#define FE_DIVBYZERO FE_DIVBYZERO - FE_UNDERFLOW = 1 << 5, -#define FE_UNDERFLOW FE_UNDERFLOW - FE_OVERFLOW = 1 << 6, -#define FE_OVERFLOW FE_OVERFLOW - FE_INVALID = 1 << 7 -#define FE_INVALID FE_INVALID + FE_INEXACT = +# define FE_INEXACT (1 << 3) + FE_INEXACT, + FE_DIVBYZERO = +# define FE_DIVBYZERO (1 << 4) + FE_DIVBYZERO, + FE_UNDERFLOW = +# define FE_UNDERFLOW (1 << 5) + FE_UNDERFLOW, + FE_OVERFLOW = +# define FE_OVERFLOW (1 << 6) + FE_OVERFLOW, + FE_INVALID = +# define FE_INVALID (1 << 7) + FE_INVALID }; -#define FE_ALL_EXCEPT \ +# define FE_ALL_EXCEPT \ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) /* The m68k FPU supports all of the four defined rounding modes. We use @@ -44,21 +50,45 @@ enum appropriate macros. */ enum { - FE_TONEAREST = 0, -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = 1 << 4, -#define FE_TOWARDZERO FE_TOWARDZERO - FE_DOWNWARD = 2 << 4, -#define FE_DOWNWARD FE_DOWNWARD - FE_UPWARD = 3 << 4 -#define FE_UPWARD FE_UPWARD + FE_TONEAREST = +# define FE_TONEAREST 0 + FE_TONEAREST, + FE_TOWARDZERO = +# define FE_TOWARDZERO (1 << 4) + FE_TOWARDZERO, + FE_DOWNWARD = +# define FE_DOWNWARD (2 << 4) + FE_DOWNWARD, + FE_UPWARD = +# define FE_UPWARD (3 << 4) + FE_UPWARD }; +#else + +/* In the soft-float case, only rounding to nearest is supported, with + no exceptions. */ + +# define FE_ALL_EXCEPT 0 + +enum + { + __FE_UNDEFINED = -1, + + FE_TONEAREST = +# define FE_TONEAREST 0 + FE_TONEAREST + }; + +#endif + /* Type representing exception flags. */ typedef unsigned int fexcept_t; +#if defined __HAVE_68881__ || defined __HAVE_FPU__ || defined __mcffpu__ + /* Type representing floating-point environment. This structure corresponds to the layout of the block written by `fmovem'. */ typedef struct @@ -69,10 +99,30 @@ typedef struct } fenv_t; +#else + +/* Keep ABI compatibility with the type used in the generic + bits/fenv.h, formerly used for no-FPU ColdFire. */ +typedef struct + { + fexcept_t __excepts; + } +fenv_t; + +#endif + /* If the default argument is used we use this value. */ #define FE_DFL_ENV ((const fenv_t *) -1) -#ifdef __USE_GNU +#if defined __USE_GNU && (defined __HAVE_68881__ \ + || defined __HAVE_FPU__ \ + || defined __mcffpu__) /* Floating-point environment where none of the exceptions are masked. */ # define FE_NOMASK_ENV ((const fenv_t *) -2) #endif + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/m68k/bits/shm.h b/libc/sysdeps/linux/m68k/bits/shm.h new file mode 100644 index 000000000..aa1a72e54 --- /dev/null +++ b/libc/sysdeps/linux/m68k/bits/shm.h @@ -0,0 +1,108 @@ +/* Copyright (C) 1995,1996,1997,2000,2002,2004 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 + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_SHM_H +# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead." +#endif + +#include <bits/types.h> + +/* Permission flag for shmget. */ +#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */ +#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */ + +/* Flags for `shmat'. */ +#define SHM_RDONLY 010000 /* attach read-only else read-write */ +#define SHM_RND 020000 /* round attach address to SHMLBA */ +#define SHM_REMAP 040000 /* take-over region on attach */ + +/* Commands for `shmctl'. */ +#define SHM_LOCK 11 /* lock segment (root only) */ +#define SHM_UNLOCK 12 /* unlock segment (root only) */ + +__BEGIN_DECLS + +/* Segment low boundary address multiple. */ +#define SHMLBA (__getpagesize () << 2) +extern int __getpagesize (void) __THROW __attribute__ ((__const__)); + + +/* Type to count number of attaches. */ +typedef unsigned long int shmatt_t; + +/* Data structure describing a set of semaphores. */ +struct shmid_ds + { + struct ipc_perm shm_perm; /* operation permission struct */ + size_t shm_segsz; /* size of segment in bytes */ +#if defined(__UCLIBC_USE_TIME64__) + __time_t shm_atime; + __time_t shm_dtime; + __time_t shm_ctime; +#else + __time_t shm_atime; /* time of last shmat() */ + unsigned long int __uclibc_unused1; + __time_t shm_dtime; /* time of last shmdt() */ + unsigned long int __uclibc_unused2; + __time_t shm_ctime; /* time of last change by shmctl() */ + unsigned long int __uclibc_unused3; +#endif + __pid_t shm_cpid; /* pid of creator */ + __pid_t shm_lpid; /* pid of last shmop */ + shmatt_t shm_nattch; /* number of current attaches */ + unsigned long int __uclibc_unused4; + unsigned long int __uclibc_unused5; + }; + +#ifdef __USE_MISC + +/* ipcs ctl commands */ +# define SHM_STAT 13 +# define SHM_INFO 14 + +/* shm_mode upper byte flags */ +# define SHM_DEST 01000 /* segment will be destroyed on last detach */ +# define SHM_LOCKED 02000 /* segment will not be swapped */ +# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */ +# define SHM_NORESERVE 010000 /* don't check for reservations */ + +struct shminfo + { + unsigned long int shmmax; + unsigned long int shmmin; + unsigned long int shmmni; + unsigned long int shmseg; + unsigned long int shmall; + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; + unsigned long int __uclibc_unused3; + unsigned long int __uclibc_unused4; + }; + +struct shm_info + { + int used_ids; + unsigned long int shm_tot; /* total allocated shm */ + unsigned long int shm_rss; /* total resident shm */ + unsigned long int shm_swp; /* total swapped shm */ + unsigned long int swap_attempts; + unsigned long int swap_successes; + }; + +#endif /* __USE_MISC */ + +__END_DECLS diff --git a/libc/sysdeps/linux/m68k/bits/stat.h b/libc/sysdeps/linux/m68k/bits/stat.h index 7b9c3d144..70da1b384 100644 --- a/libc/sysdeps/linux/m68k/bits/stat.h +++ b/libc/sysdeps/linux/m68k/bits/stat.h @@ -60,7 +60,7 @@ struct stat #else __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ #endif -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -106,7 +106,7 @@ struct stat64 __blksize_t st_blksize; /* Optimal block size for I/O. */ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the diff --git a/libc/sysdeps/linux/m68k/bsd-_setjmp.S b/libc/sysdeps/linux/m68k/bsd-_setjmp.S index c963cccf5..eaabce8ed 100644 --- a/libc/sysdeps/linux/m68k/bsd-_setjmp.S +++ b/libc/sysdeps/linux/m68k/bsd-_setjmp.S @@ -13,7 +13,9 @@ _setjmp: moveal %sp@(4), %a0 movel %sp@(0), %a0@(JB_PC) moveml %d2-%d7/%a2-%a7, %a0@(JB_REGS) -#if defined __HAVE_68881__ || defined __UCLIBC_HAS_FPU__ +#if defined(__mcffpu__) && defined(__UCLIBC_HAS_FPU__) + fmovemd %fp2-%fp7, %a0@(JB_FPREGS) +#elif defined(__HAVE_68881__) fmovemx %fp2-%fp7, %a0@(JB_FPREGS) #endif clrl %d0 diff --git a/libc/sysdeps/linux/m68k/bsd-setjmp.S b/libc/sysdeps/linux/m68k/bsd-setjmp.S index 9daf27713..7d76d192b 100644 --- a/libc/sysdeps/linux/m68k/bsd-setjmp.S +++ b/libc/sysdeps/linux/m68k/bsd-setjmp.S @@ -14,7 +14,9 @@ setjmp: moveal %sp@(4), %a0 movel %sp@(0), %a0@(JB_PC) moveml %d2-%d7/%a2-%a7, %a0@(JB_REGS) -#if defined __HAVE_68881__ || defined __UCLIBC_HAS_FPU__ +#if defined(__mcffpu__) && defined(__UCLIBC_HAS_FPU__) + fmovemd %fp2-%fp7, %a0@(JB_FPREGS) +#elif defined(__HAVE_68881__) fmovemx %fp2-%fp7, %a0@(JB_FPREGS) #endif clrl %d0 diff --git a/libc/sysdeps/linux/m68k/clone.S b/libc/sysdeps/linux/m68k/clone.S index 24071235b..a83d90a98 100644 --- a/libc/sysdeps/linux/m68k/clone.S +++ b/libc/sysdeps/linux/m68k/clone.S @@ -35,12 +35,14 @@ __clone: /* Sanity check arguments. */ - movel #-EINVAL, %d0 - movel 4(%sp), %a0 /* no NULL function pointers */ - tstl %a0 + movel #-EINVAL, %d0 + movel 4(%sp), %d1 /* no NULL function pointers */ + movel %d1, %a0 + tstl %d1 beq.w __syscall_error_trampoline - movel 8(%sp), %a1 /* no NULL stack pointers */ - tstl %a1 + movel 8(%sp), %d1 /* no NULL stack pointers */ + movel %d1, %a1 + tstl %d1 beq.w __syscall_error_trampoline /* Allocate space and copy the argument onto the new stack. */ diff --git a/libc/sysdeps/linux/m68k/fpu_control.h b/libc/sysdeps/linux/m68k/fpu_control.h index 35ad95e6d..c3a9c6326 100644 --- a/libc/sysdeps/linux/m68k/fpu_control.h +++ b/libc/sysdeps/linux/m68k/fpu_control.h @@ -1,6 +1,5 @@ /* 68k FPU control word definitions. - Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. - This file is part of the GNU C Library. + Copyright (C) 1996-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -13,8 +12,8 @@ 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 - <http://www.gnu.org/licenses/>. */ + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ #ifndef _FPU_CONTROL_H #define _FPU_CONTROL_H @@ -29,9 +28,9 @@ * 12 -> enable trap for OVFL exception * 11 -> enable trap for UNFL exception * 10 -> enable trap for DZ exception - * 9 -> enable trap for INEX2 exception - * 8 -> enable trap for INEX1 exception - * 7-6 -> Precision Control + * 9 -> enable trap for INEX2 exception (INEX on Coldfire) + * 8 -> enable trap for INEX1 exception (IDE on Coldfire) + * 7-6 -> Precision Control (only bit 6 is used on Coldfire) * 5-4 -> Rounding Control * 3-0 -> zero (read as 0, write as 0) * @@ -53,50 +52,66 @@ #include <features.h> +#if defined (__mcoldfire__) && !defined (__mcffpu__) + +# define _FPU_RESERVED 0xffffffff +# define _FPU_DEFAULT 0x00000000 +# define _FPU_GETCW(cw) ((cw) = 0) +# define _FPU_SETCW(cw) ((void) (cw)) + +#else + /* masking of interrupts */ -#define _FPU_MASK_BSUN 0x8000 -#define _FPU_MASK_SNAN 0x4000 -#define _FPU_MASK_OPERR 0x2000 -#define _FPU_MASK_OVFL 0x1000 -#define _FPU_MASK_UNFL 0x0800 -#define _FPU_MASK_DZ 0x0400 -#define _FPU_MASK_INEX1 0x0200 -#define _FPU_MASK_INEX2 0x0100 +# define _FPU_MASK_BSUN 0x8000 +# define _FPU_MASK_SNAN 0x4000 +# define _FPU_MASK_OPERR 0x2000 +# define _FPU_MASK_OVFL 0x1000 +# define _FPU_MASK_UNFL 0x0800 +# define _FPU_MASK_DZ 0x0400 +# define _FPU_MASK_INEX1 0x0200 +# define _FPU_MASK_INEX2 0x0100 /* precision control */ -#define _FPU_EXTENDED 0x00 /* RECOMMENDED */ -#define _FPU_DOUBLE 0x80 -#define _FPU_SINGLE 0x40 /* DO NOT USE */ +# ifdef __mcoldfire__ +# define _FPU_DOUBLE 0x00 +# else +# define _FPU_EXTENDED 0x00 /* RECOMMENDED */ +# define _FPU_DOUBLE 0x80 +# endif +# define _FPU_SINGLE 0x40 /* DO NOT USE */ /* rounding control */ -#define _FPU_RC_NEAREST 0x00 /* RECOMMENDED */ -#define _FPU_RC_ZERO 0x10 -#define _FPU_RC_DOWN 0x20 -#define _FPU_RC_UP 0x30 +# define _FPU_RC_NEAREST 0x00 /* RECOMMENDED */ +# define _FPU_RC_ZERO 0x10 +# define _FPU_RC_DOWN 0x20 +# define _FPU_RC_UP 0x30 -#define _FPU_RESERVED 0xFFFF000F /* Reserved bits in fpucr */ +# ifdef __mcoldfire__ +# define _FPU_RESERVED 0xFFFF800F +# else +# define _FPU_RESERVED 0xFFFF000F /* Reserved bits in fpucr */ +# endif /* Now two recommended fpucr */ /* The fdlibm code requires no interrupts for exceptions. Don't change the rounding mode, it would break long double I/O! */ -#define _FPU_DEFAULT 0x00000000 +# define _FPU_DEFAULT 0x00000000 /* IEEE: same as above, but exceptions. We must make it non-zero so that __setfpucw works. This bit will be ignored. */ -#define _FPU_IEEE 0x00000001 +# define _FPU_IEEE 0x00000001 + +/* Macros for accessing the hardware control word. */ +# define _FPU_GETCW(cw) __asm__ ("fmove%.l %!, %0" : "=dm" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("fmove%.l %0, %!" : : "dm" (cw)) +#endif /* Type of the control word. */ typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__))); -/* Macros for accessing the hardware control word. */ -#define _FPU_GETCW(cw) __asm__ ("fmove%.l %!, %0" : "=dm" (cw)) -#define _FPU_SETCW(cw) __asm__ __volatile__ ("fmove%.l %0, %!" : : "dm" (cw)) - -#if 0 /* Default control word set at startup. */ extern fpu_control_t __fpu_control; -#endif #endif /* _M68K_FPU_CONTROL_H */ diff --git a/libc/sysdeps/linux/m68k/setjmp.S b/libc/sysdeps/linux/m68k/setjmp.S index 5f05b8591..d10163ec6 100644 --- a/libc/sysdeps/linux/m68k/setjmp.S +++ b/libc/sysdeps/linux/m68k/setjmp.S @@ -14,7 +14,9 @@ __sigsetjmp: moveal %sp@(4), %a0 movel %sp@(0), %a0@(JB_PC) moveml %d2-%d7/%a2-%a7, %a0@(JB_REGS) -#if defined __HAVE_68881__ || defined __UCLIBC_HAS_FPU__ +#if defined(__mcffpu__) && defined (__UCLIBC_HAS_FPU__) + fmovemd %fp2-%fp7, %a0@(JB_FPREGS) +#elif defined(__HAVE_68881__) fmovemx %fp2-%fp7, %a0@(JB_FPREGS) #endif clrl %d0 diff --git a/libc/sysdeps/linux/metag/bits/fcntl.h b/libc/sysdeps/linux/metag/bits/fcntl.h index bdd697348..471938b7d 100644 --- a/libc/sysdeps/linux/metag/bits/fcntl.h +++ b/libc/sysdeps/linux/metag/bits/fcntl.h @@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/microblaze/bits/fcntl.h b/libc/sysdeps/linux/microblaze/bits/fcntl.h index 110927d95..8c9c2ceef 100644 --- a/libc/sysdeps/linux/microblaze/bits/fcntl.h +++ b/libc/sysdeps/linux/microblaze/bits/fcntl.h @@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/mips/bits/fcntl.h b/libc/sysdeps/linux/mips/bits/fcntl.h index 33251c74d..a98b8c2e5 100644 --- a/libc/sysdeps/linux/mips/bits/fcntl.h +++ b/libc/sysdeps/linux/mips/bits/fcntl.h @@ -268,3 +268,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/mips/bits/fenv.h b/libc/sysdeps/linux/mips/bits/fenv.h index 944101f75..25ae4d9ca 100644 --- a/libc/sysdeps/linux/mips/bits/fenv.h +++ b/libc/sysdeps/linux/mips/bits/fenv.h @@ -1,5 +1,4 @@ -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* Copyright (C) 1998-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -12,31 +11,38 @@ 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 - <http://www.gnu.org/licenses/>. */ + 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 +#ifdef __mips_hard_float + /* Define bits representing the exception. We use the bit positions of the appropriate bits in the FPU control word. */ enum { - FE_INEXACT = 0x04, -#define FE_INEXACT FE_INEXACT - FE_UNDERFLOW = 0x08, -#define FE_UNDERFLOW FE_UNDERFLOW - FE_OVERFLOW = 0x10, -#define FE_OVERFLOW FE_OVERFLOW - FE_DIVBYZERO = 0x20, -#define FE_DIVBYZERO FE_DIVBYZERO - FE_INVALID = 0x40, -#define FE_INVALID FE_INVALID + FE_INEXACT = +# define FE_INEXACT 0x04 + FE_INEXACT, + FE_UNDERFLOW = +# define FE_UNDERFLOW 0x08 + FE_UNDERFLOW, + FE_OVERFLOW = +# define FE_OVERFLOW 0x10 + FE_OVERFLOW, + FE_DIVBYZERO = +# define FE_DIVBYZERO 0x20 + FE_DIVBYZERO, + FE_INVALID = +# define FE_INVALID 0x40 + FE_INVALID, }; -#define FE_ALL_EXCEPT \ +# define FE_ALL_EXCEPT \ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) /* The MIPS FPU supports all of the four defined rounding modes. We @@ -44,16 +50,38 @@ enum for the appropriate macros. */ enum { - FE_TONEAREST = 0x0, -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = 0x1, -#define FE_TOWARDZERO FE_TOWARDZERO - FE_UPWARD = 0x2, -#define FE_UPWARD FE_UPWARD - FE_DOWNWARD = 0x3 -#define FE_DOWNWARD FE_DOWNWARD + FE_TONEAREST = +# define FE_TONEAREST 0x0 + FE_TONEAREST, + FE_TOWARDZERO = +# define FE_TOWARDZERO 0x1 + FE_TOWARDZERO, + FE_UPWARD = +# define FE_UPWARD 0x2 + FE_UPWARD, + FE_DOWNWARD = +# define FE_DOWNWARD 0x3 + FE_DOWNWARD }; +#else + +/* In the soft-float case, only rounding to nearest is supported, with + no exceptions. */ + +enum + { + __FE_UNDEFINED = -1, + + FE_TONEAREST = +# define FE_TONEAREST 0x0 + FE_TONEAREST + }; + +# define FE_ALL_EXCEPT 0 + +#endif + /* Type representing exception flags. */ typedef unsigned short int fexcept_t; @@ -70,7 +98,13 @@ fenv_t; /* If the default argument is used we use this value. */ #define FE_DFL_ENV ((const fenv_t *) -1) -#ifdef __USE_GNU +#if defined __USE_GNU && defined __mips_hard_float /* Floating-point environment where none of the exception is masked. */ # define FE_NOMASK_ENV ((const fenv_t *) -2) #endif + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/mips/bits/msq.h b/libc/sysdeps/linux/mips/bits/msq.h index bcf1073e8..141b1ff9f 100644 --- a/libc/sysdeps/linux/mips/bits/msq.h +++ b/libc/sysdeps/linux/mips/bits/msq.h @@ -35,30 +35,58 @@ typedef unsigned long int msglen_t; /* Structure of record for one message inside the kernel. The type `struct msg' is opaque. */ +#if (__WORDSIZE == 32) && defined(__MIPSEL__) struct msqid_ds { struct ipc_perm msg_perm; /* structure describing operation permission */ -#if (__WORDSIZE == 32) && !defined(__MIPSEL__) - unsigned long __unused1; -#endif - __time_t msg_stime; /* time of last msgsnd command */ -#if (__WORDSIZE == 32) && defined(__MIPSEL__) - unsigned long __unused1; -#endif -#if (__WORDSIZE == 32) && !defined(__MIPSEL__) - unsigned long __unused2; -#endif - __time_t msg_rtime; /* time of last msgrcv command */ -#if (__WORDSIZE == 32) && defined(__MIPSEL__) - unsigned long __unused2; -#endif -#if (__WORDSIZE == 32) && !defined(__MIPSEL__) - unsigned long __unused3; -#endif - __time_t msg_ctime; /* time of last change */ -#if (__WORDSIZE == 32) && defined(__MIPSEL__) - unsigned long __unused3; -#endif +# if defined(__UCLIBC_USE_TIME64__) + unsigned long msg_stime_internal_1; /* time of last msgsnd command */ + unsigned long msg_stime_internal_2; + unsigned long msg_rtime_internal_1; /* time of last msgrcv command */ + unsigned long msg_rtime_internal_2; + unsigned long msg_ctime_internal_1; /* time of last change */ + unsigned long msg_ctime_internal_2; +# else + __time_t msg_stime; + unsigned long int __uclibc_unused1; + __time_t msg_rtime; + unsigned long int __uclibc_unused2; + __time_t msg_ctime; + unsigned long int __uclibc_unused3; +# endif + unsigned long int __msg_cbytes; /* current number of bytes on queue */ + msgqnum_t msg_qnum; /* number of messages currently on queue */ + msglen_t msg_qbytes; /* max number of bytes allowed on queue */ + __pid_t msg_lspid; /* pid of last msgsnd() */ + __pid_t msg_lrpid; /* pid of last msgrcv() */ + unsigned long int __uclibc_unused4; + unsigned long int __uclibc_unused5; +# if defined(__UCLIBC_USE_TIME64__) + __time_t msg_stime; + __time_t msg_rtime; + __time_t msg_ctime; +# endif +}; + +#elif (__WORDSIZE == 32) && defined(__MIPSEB__) +struct msqid_ds +{ + struct ipc_perm msg_perm; /* structure describing operation permission */ +# if defined(__UCLIBC_USE_TIME64__) + unsigned long msg_stime_internal_2; /* time of last msgsnd command */ + unsigned long msg_stime_internal_1; + unsigned long msg_rtime_internal_2; /* time of last msgrcv command */ + unsigned long msg_rtime_internal_1; + unsigned long msg_ctime_internal_2; /* time of last change */ + unsigned long msg_ctime_internal_1; +# else + unsigned long int __uclibc_unused1; + __time_t msg_stime; + unsigned long int __uclibc_unused2; + __time_t msg_rtime; + unsigned long int __uclibc_unused3; + __time_t msg_ctime; +# endif unsigned long int __msg_cbytes; /* current number of bytes on queue */ msgqnum_t msg_qnum; /* number of messages currently on queue */ msglen_t msg_qbytes; /* max number of bytes allowed on queue */ @@ -66,8 +94,32 @@ struct msqid_ds __pid_t msg_lrpid; /* pid of last msgrcv() */ unsigned long int __uclibc_unused4; unsigned long int __uclibc_unused5; +# if defined(__UCLIBC_USE_TIME64__) + __time_t msg_stime; + __time_t msg_rtime; + __time_t msg_ctime; +# endif +}; + +#else + +struct msqid_ds +{ + struct ipc_perm msg_perm; /* structure describing operation permission */ + __time_t msg_stime; /* time of last msgsnd command */ + __time_t msg_rtime; /* time of last msgrcv command */ + __time_t msg_ctime; /* time of last change */ + unsigned long int __msg_cbytes; /* current number of bytes on queue */ + msgqnum_t msg_qnum; /* number of messages currently on queue */ + msglen_t msg_qbytes; /* max number of bytes allowed on queue */ + __pid_t msg_lspid; /* pid of last msgsnd() */ + __pid_t msg_lrpid; /* pid of last msgrcv() */ + unsigned long int __uclibc_unused4; + unsigned long int __uclibc_unused5; }; +#endif + #ifdef __USE_MISC # define msg_cbytes __msg_cbytes diff --git a/libc/sysdeps/linux/mips/bits/sem.h b/libc/sysdeps/linux/mips/bits/sem.h index 35eaa05c3..230d04868 100644 --- a/libc/sysdeps/linux/mips/bits/sem.h +++ b/libc/sysdeps/linux/mips/bits/sem.h @@ -38,22 +38,23 @@ struct semid_ds { struct ipc_perm sem_perm; /* operation permission struct */ -#if defined(__UCLIBC_USE_TIME64__) +#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) unsigned long int __sem_otime_internal_1; /* last semop() time */ - unsigned long int __sem_otime_internal_2; unsigned long int __sem_ctime_internal_1; /* last time changed by semctl() */ - unsigned long int __sem_ctime_internal_2; #else __time_t sem_otime; /* last semop() time */ __time_t sem_ctime; /* last time changed by semctl() */ #endif unsigned long int sem_nsems; /* number of semaphores in set */ -#if defined(__UCLIBC_USE_TIME64__) +#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) + unsigned long int __sem_otime_internal_2; + unsigned long int __sem_ctime_internal_2; __time_t sem_otime; __time_t sem_ctime; -#endif +#else unsigned long int __uclibc_unused1; unsigned long int __uclibc_unused2; +#endif }; /* The user should define a union like the following to use it for arguments diff --git a/libc/sysdeps/linux/mips/bits/shm.h b/libc/sysdeps/linux/mips/bits/shm.h index bb87ba13d..1855a50b2 100644 --- a/libc/sysdeps/linux/mips/bits/shm.h +++ b/libc/sysdeps/linux/mips/bits/shm.h @@ -46,14 +46,32 @@ struct shmid_ds { struct ipc_perm shm_perm; /* operation permission struct */ size_t shm_segsz; /* size of segment in bytes */ - __time_t shm_atime; /* time of last shmat() */ - __time_t shm_dtime; /* time of last shmdt() */ - __time_t shm_ctime; /* time of last change by shmctl() */ +#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) + unsigned long int shm_atime_internal_1; /* time of last shmat() */ + unsigned long int shm_dtime_internal_1; /* time of last shmdt() */ + unsigned long int shm_ctime_internal_1; /* time of last change by shmctl() */ +#else + __time_t shm_atime; + __time_t shm_dtime; + __time_t shm_ctime; +#endif __pid_t shm_cpid; /* pid of creator */ __pid_t shm_lpid; /* pid of last shmop */ shmatt_t shm_nattch; /* number of current attaches */ - unsigned long int __uclibc_unused1; - unsigned long int __uclibc_unused2; +#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) + unsigned short int shm_atime_internal_2; /* time of last shmat() */ + unsigned short int shm_dtime_internal_2; /* time of last shmdt() */ + unsigned short int shm_ctime_internal_2; /* time of last change by shmctl() */ + unsigned short int __uclibc_unused1; + __time_t shm_atime; + __time_t shm_dtime; + __time_t shm_ctime; +#else + unsigned short int __uclibc_unused1; + unsigned short int __uclibc_unused2; + unsigned short int __uclibc_unused3; + unsigned short int __uclibc_unused4; +#endif }; #ifdef __USE_MISC diff --git a/libc/sysdeps/linux/mips/bits/stat.h b/libc/sysdeps/linux/mips/bits/stat.h index 539fa33d2..81d2e4687 100644 --- a/libc/sysdeps/linux/mips/bits/stat.h +++ b/libc/sysdeps/linux/mips/bits/stat.h @@ -60,7 +60,7 @@ struct stat long int st_pad2[2]; __off64_t st_size; /* Size of file, in bytes. */ #endif -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -103,7 +103,7 @@ struct stat { unsigned int st_rdev; /* Device number, if device. */ int st_pad2[3]; __off_t st_size; /* Size of file, in bytes. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -145,7 +145,7 @@ struct stat64 __dev_t st_rdev; /* Device number, if device. */ long int st_pad2[2]; __off64_t st_size; /* Size of file, in bytes. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -184,7 +184,7 @@ struct stat64 { unsigned int st_rdev; /* Device number, if device. */ int st_pad2[3]; __off_t st_size; /* Size of file, in bytes. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the diff --git a/libc/sysdeps/linux/mips/bits/syscalls.h b/libc/sysdeps/linux/mips/bits/syscalls.h index 13728ac55..64b42ffb1 100644 --- a/libc/sysdeps/linux/mips/bits/syscalls.h +++ b/libc/sysdeps/linux/mips/bits/syscalls.h @@ -184,7 +184,7 @@ ({ \ long _sys_result; \ \ - FORCE_FRAME_POINTER; \ + int* array = FORCE_FRAME_POINTER; \ { \ register long __v0 __asm__("$2") ncs_init; \ register long __a0 __asm__("$4") = (long) arg1; \ @@ -193,15 +193,16 @@ register long __a3 __asm__("$7") = (long) arg4; \ __asm__ __volatile__ ( \ ".set\tnoreorder\n\t" \ - "subu\t$29, 32\n\t" \ + "subu\t$29, 32\n\t" \ "sw\t%6, 16($29)\n\t" \ cs_init \ "syscall\n\t" \ - "addiu\t$29, 32\n\t" \ - ".set\treorder" \ + "addiu\t$29, 32\n\t" \ + "addiu\t%7, %7, 0\n\t" \ + ".set\treorder" \ : "=r" (__v0), "+r" (__a3) \ : input, "r" (__a0), "r" (__a1), "r" (__a2), \ - "r" ((long)arg5) \ + "r" ((long)arg5), "r" (array) \ : __SYSCALL_CLOBBERS); \ err = __a3; \ _sys_result = __v0; \ @@ -213,7 +214,7 @@ ({ \ long _sys_result; \ \ - FORCE_FRAME_POINTER; \ + int* array = FORCE_FRAME_POINTER; \ { \ register long __v0 __asm__("$2") ncs_init; \ register long __a0 __asm__("$4") = (long) arg1; \ @@ -221,17 +222,18 @@ register long __a2 __asm__("$6") = (long) arg3; \ register long __a3 __asm__("$7") = (long) arg4; \ __asm__ __volatile__ ( \ - ".set\tnoreorder\n\t" \ - "subu\t$29, 32\n\t" \ + ".set\tnoreorder\n\t" \ + "subu\t$29, 32\n\t" \ "sw\t%6, 16($29)\n\t" \ "sw\t%7, 20($29)\n\t" \ cs_init \ "syscall\n\t" \ - "addiu\t$29, 32\n\t" \ - ".set\treorder" \ + "addiu\t$29, 32\n\t" \ + "addiu\t%8, %8, 0\n\t" \ + ".set\treorder" \ : "=r" (__v0), "+r" (__a3) \ : input, "r" (__a0), "r" (__a1), "r" (__a2), \ - "r" ((long)arg5), "r" ((long)arg6) \ + "r" ((long)arg5), "r" ((long)arg6), "r" (array) \ : __SYSCALL_CLOBBERS); \ err = __a3; \ _sys_result = __v0; \ @@ -243,7 +245,7 @@ ({ \ long _sys_result; \ \ - FORCE_FRAME_POINTER; \ + int* array = FORCE_FRAME_POINTER; \ { \ register long __v0 __asm__("$2") ncs_init; \ register long __a0 __asm__("$4") = (long) arg1; \ @@ -252,17 +254,19 @@ register long __a3 __asm__("$7") = (long) arg4; \ __asm__ __volatile__ ( \ ".set\tnoreorder\n\t" \ - "subu\t$29, 32\n\t" \ + "subu\t$29, 32\n\t" \ "sw\t%6, 16($29)\n\t" \ "sw\t%7, 20($29)\n\t" \ "sw\t%8, 24($29)\n\t" \ cs_init \ "syscall\n\t" \ - "addiu\t$29, 32\n\t" \ - ".set\treorder" \ + "addiu\t$29, 32\n\t" \ + "addiu\t%9, %9, 0\n\t" \ + ".set\treorder" \ : "=r" (__v0), "+r" (__a3) \ : input, "r" (__a0), "r" (__a1), "r" (__a2), \ - "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7) \ + "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7), \ + "r" (array) \ : __SYSCALL_CLOBBERS); \ err = __a3; \ _sys_result = __v0; \ diff --git a/libc/sysdeps/linux/mips/fpu_control.h b/libc/sysdeps/linux/mips/fpu_control.h index f855af506..6aa05e4cf 100644 --- a/libc/sysdeps/linux/mips/fpu_control.h +++ b/libc/sysdeps/linux/mips/fpu_control.h @@ -1,7 +1,5 @@ /* FPU control word bits. Mips version. - Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Olaf Flebbe and Ralf Baechle. + Copyright (C) 1996-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -14,8 +12,8 @@ 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 - <http://www.gnu.org/licenses/>. */ + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ #ifndef _FPU_CONTROL_H #define _FPU_CONTROL_H @@ -28,7 +26,10 @@ * causing unimplemented operation exception. This bit is only * available for MIPS III and newer. * 23 -> Condition bit - * 22-18 -> reserved (read as 0, write with 0) + * 22-21 -> reserved for architecture implementers + * 20 -> reserved (read as 0, write with 0) + * 19 -> IEEE 754-2008 non-arithmetic ABS.fmt and NEG.fmt enable + * 18 -> IEEE 754-2008 recommended NaN encoding enable * 17 -> cause bit for unimplemented operation * 16 -> cause bit for invalid exception * 15 -> cause bit for division by zero exception @@ -57,43 +58,74 @@ #include <features.h> -/* masking of interrupts */ +#ifdef __mips_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 /* __mips_soft_float */ + +/* Masks for interrupts. */ #define _FPU_MASK_V 0x0800 /* Invalid operation */ #define _FPU_MASK_Z 0x0400 /* Division by zero */ #define _FPU_MASK_O 0x0200 /* Overflow */ #define _FPU_MASK_U 0x0100 /* Underflow */ #define _FPU_MASK_I 0x0080 /* Inexact operation */ -/* flush denormalized numbers to zero */ +/* Flush denormalized numbers to zero. */ #define _FPU_FLUSH_TZ 0x1000000 -/* rounding control */ +/* IEEE 754-2008 compliance control. */ +#define _FPU_ABS2008 0x80000 +#define _FPU_NAN2008 0x40000 + +/* Rounding control. */ #define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */ #define _FPU_RC_ZERO 0x1 #define _FPU_RC_UP 0x2 #define _FPU_RC_DOWN 0x3 +/* Mask for rounding control. */ +#define _FPU_RC_MASK 0x3 -#define _FPU_RESERVED 0xfe3c0000 /* Reserved bits in cw */ +#define _FPU_RESERVED 0xfe8c0000 /* Reserved bits in cw, incl ABS/NAN2008. */ /* The fdlibm code requires strict IEEE double precision arithmetic, and no interrupts for exceptions, rounding to nearest. */ +#ifdef __mips_nan2008 +# define _FPU_DEFAULT 0x000C0000 +#else +# define _FPU_DEFAULT 0x00000000 +#endif -#define _FPU_DEFAULT 0x00000000 - -/* IEEE: same as above, but exceptions */ -#define _FPU_IEEE 0x00000F80 +/* IEEE: same as above, but exceptions. */ +#ifdef __mips_nan2008 +# define _FPU_IEEE 0x000C0F80 +#else +# define _FPU_IEEE 0x00000F80 +#endif /* Type of the control word. */ typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__))); /* Macros for accessing the hardware control word. */ -#define _FPU_GETCW(cw) __asm__ ("cfc1 %0,$31" : "=r" (cw)) -#define _FPU_SETCW(cw) __asm__ ("ctc1 %0,$31" : : "r" (cw)) +extern fpu_control_t __mips_fpu_getcw (void) __THROW; +extern void __mips_fpu_setcw (fpu_control_t) __THROW; +#ifdef __mips16 +# define _FPU_GETCW(cw) do { (cw) = __mips_fpu_getcw (); } while (0) +# define _FPU_SETCW(cw) __mips_fpu_setcw (cw) +#else +# define _FPU_GETCW(cw) __asm__ volatile ("cfc1 %0,$31" : "=r" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("ctc1 %0,$31" : : "r" (cw)) +#endif -#if 0 /* Default control word set at startup. */ extern fpu_control_t __fpu_control; -#endif + +#endif /* __mips_soft_float */ #endif /* fpu_control.h */ diff --git a/libc/sysdeps/linux/nds32/Makefile.arch b/libc/sysdeps/linux/nds32/Makefile.arch index c7627b847..caf163844 100644 --- a/libc/sysdeps/linux/nds32/Makefile.arch +++ b/libc/sysdeps/linux/nds32/Makefile.arch @@ -2,6 +2,6 @@ # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. CSRC-y := brk.c prctl.c mremap.c -SSRC-y := setjmp.S __longjmp.S bsd-setjmp.S bsd-_setjmp.S clone.S sysdep.S +SSRC-y := setjmp.S __longjmp.S bsd-setjmp.S bsd-_setjmp.S clone.S vfork.S sysdep.S CSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.c swapcontext.c SSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += getcontext.S setcontext.S diff --git a/libc/sysdeps/linux/nds32/bits/fcntl.h b/libc/sysdeps/linux/nds32/bits/fcntl.h index 2e6a95ec8..cfce8ab27 100644 --- a/libc/sysdeps/linux/nds32/bits/fcntl.h +++ b/libc/sysdeps/linux/nds32/bits/fcntl.h @@ -249,3 +249,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/nds32/bits/kernel_types.h b/libc/sysdeps/linux/nds32/bits/kernel_types.h index 6b142d2e5..1b6ae4d1b 100644 --- a/libc/sysdeps/linux/nds32/bits/kernel_types.h +++ b/libc/sysdeps/linux/nds32/bits/kernel_types.h @@ -14,13 +14,13 @@ typedef unsigned short __kernel_dev_t; typedef unsigned long __kernel_ino_t; -typedef unsigned int __kernel_mode_t; +typedef unsigned short __kernel_mode_t; typedef unsigned short __kernel_nlink_t; typedef long __kernel_off_t; typedef int __kernel_pid_t; -typedef int __kernel_ipc_pid_t; -typedef unsigned int __kernel_uid_t; -typedef unsigned int __kernel_gid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; typedef unsigned int __kernel_size_t; typedef int __kernel_ssize_t; typedef int __kernel_ptrdiff_t; @@ -34,11 +34,19 @@ typedef unsigned short __kernel_gid16_t; typedef unsigned int __kernel_uid32_t; typedef unsigned int __kernel_gid32_t; -typedef __kernel_uid_t __kernel_old_uid_t; -typedef __kernel_gid_t __kernel_old_gid_t; -typedef unsigned int __kernel_old_dev_t; +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef __kernel_dev_t __kernel_old_dev_t; typedef long __kernel_long_t; typedef unsigned long __kernel_ulong_t; __extension__ typedef long long __kernel_loff_t; +typedef struct { +#ifdef __USE_ALL + int val[2]; +#else + int __val[2]; +#endif +} __kernel_fsid_t; + #endif /* __ARCH_NDS32_POSIX_TYPES_H */ diff --git a/libc/sysdeps/linux/nds32/bits/stat.h b/libc/sysdeps/linux/nds32/bits/stat.h index c4e09e0f2..5272751f4 100644 --- a/libc/sysdeps/linux/nds32/bits/stat.h +++ b/libc/sysdeps/linux/nds32/bits/stat.h @@ -64,7 +64,7 @@ struct stat #else __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ #endif -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -110,7 +110,7 @@ struct stat64 __blksize_t st_blksize; /* Optimal block size for I/O. */ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the diff --git a/libc/sysdeps/linux/nds32/bits/syscalls.h b/libc/sysdeps/linux/nds32/bits/syscalls.h index 50e30db7d..a5cdda18a 100644 --- a/libc/sysdeps/linux/nds32/bits/syscalls.h +++ b/libc/sysdeps/linux/nds32/bits/syscalls.h @@ -37,7 +37,8 @@ #define Y(x) X(x) #define LIB_SYSCALL __NR_syscall -#define __issue_syscall(syscall_name) "syscall 0x0;\n" +#define __issue_syscall(syscall_name) \ +" syscall " Y(syscall_name) "; \n" #undef INTERNAL_SYSCALL_ERROR_P #define INTERNAL_SYSCALL_ERROR_P(val, err) ((unsigned int) (val) >= 0xfffff001u) diff --git a/libc/sysdeps/linux/nds32/jmpbuf-unwind.h b/libc/sysdeps/linux/nds32/jmpbuf-unwind.h index 8499e99b4..5b85f4d23 100644 --- a/libc/sysdeps/linux/nds32/jmpbuf-unwind.h +++ b/libc/sysdeps/linux/nds32/jmpbuf-unwind.h @@ -20,7 +20,7 @@ static inline uintptr_t __attribute__ ((unused)) _jmpbuf_sp (__jmp_buf regs) { - uintptr_t sp = &(regs)[0].__regs[__JMP_BUF_SP]; + uintptr_t sp = (uintptr_t) &(regs)[0].__regs[__JMP_BUF_SP]; return sp; } diff --git a/libc/sysdeps/linux/nds32/sys/ucontext.h b/libc/sysdeps/linux/nds32/sys/ucontext.h index ea86a3ad0..0d7422aab 100644 --- a/libc/sysdeps/linux/nds32/sys/ucontext.h +++ b/libc/sysdeps/linux/nds32/sys/ucontext.h @@ -36,10 +36,10 @@ typedef struct sigcontext mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { - unsigned long int __uc_flags; - struct ucontext_t *uc_link; + unsigned long int uc_flags; + struct ucontext *uc_link; stack_t uc_stack; mcontext_t uc_mcontext; __sigset_t uc_sigmask; diff --git a/libc/sysdeps/linux/nds32/vfork.S b/libc/sysdeps/linux/nds32/vfork.S new file mode 100644 index 000000000..ab32135fc --- /dev/null +++ b/libc/sysdeps/linux/nds32/vfork.S @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2016-2017 Andes Technology, Inc. + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. + Contributed by Philip Blundell <philb@gnu.org>. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#define _ERRNO_H 1 +#include <bits/errno.h> + +/* Clone the calling process, but without copying the whole address space. + The calling process is suspended until the new process exits or is + replaced by a call to `execve'. Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ + +ENTRY (__vfork) +#ifdef PIC +.pic +#endif + +#ifdef __NR_vfork + syscall __NR_vfork + bltz $r0, 2f +1: + ret +2: + sltsi $r1, $r0, -4096 + bnez $r1, 1b; + +# ifdef __ASSUME_VFORK_SYSCALL +# ifdef PIC + pushm $gp, $lp + cfi_adjust_cfa_offset(8) + cfi_rel_offset(gp, 0) + cfi_rel_offset(lp, 4) + mfusr $r15, $PC + sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_+4) + ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8) + add $gp, $gp, $r15 + + ! r15=C_SYMBOL_NAME(__syscall_error)@PLT + sethi $r15, hi20(C_SYMBOL_NAME(__syscall_error)@PLT) + ori $r15, $r15, lo12(C_SYMBOL_NAME(__syscall_error)@PLT) + add $r15, $r15, $gp + + ! jump to SYSCALL_ERROR + jral $r15 + popm $gp, $lp + cfi_adjust_cfa_offset(-8) + cfi_restore(lp) + cfi_restore(gp) + ret +# else + j C_SYMBOL_NAME(__syscall_error) +# endif +# else + /* Check if vfork syscall is known at all. */ + li $r1, -ENOSYS + beq $r0, $r1, 1f + +# ifdef PIC +3: + pushm $gp, $lp + cfi_adjust_cfa_offset(8) + cfi_rel_offset(gp, 0) + cfi_rel_offset(lp, 4) + mfusr $r15, $PC + sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_+4) + ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8) + add $gp, $gp, $r15 + + ! r15=C_SYMBOL_NAME(__syscall_error)@PLT + sethi $r15, hi20(C_SYMBOL_NAME(__syscall_error)@PLT) + ori $r15, $r15, lo12(C_SYMBOL_NAME(__syscall_error)@PLT) + add $r15, $r15, $gp + + ! jump to SYSCALL_ERROR + jral $r15 + popm $gp, $lp + cfi_adjust_cfa_offset(-8) + cfi_restore(lp) + cfi_restore(gp) + ret +# else + j C_SYMBOL_NAME(__syscall_error) +# endif +1: +# endif +#endif + +#ifndef __ASSUME_VFORK_SYSCALL + /* If we don't have vfork, fork is close enough. */ + syscall __NR_fork + bgez $r0, 1f + sltsi $r1, $r0, -4096 + bnez $r1, 1f + +# ifdef PIC + b 3b +# else + j C_SYMBOL_NAME(__syscall_error) +# endif +1: + ret + +#elif !defined __NR_vfork +# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined" +#endif + +PSEUDO_END (__vfork) +weak_alias (__vfork, vfork) +libc_hidden_def (vfork) diff --git a/libc/sysdeps/linux/nios2/bits/fcntl.h b/libc/sysdeps/linux/nios2/bits/fcntl.h index 200a35443..0c11c3aba 100644 --- a/libc/sysdeps/linux/nios2/bits/fcntl.h +++ b/libc/sysdeps/linux/nios2/bits/fcntl.h @@ -244,3 +244,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/or1k/bits/fcntl.h b/libc/sysdeps/linux/or1k/bits/fcntl.h index c9599ef3a..78eed9d5f 100644 --- a/libc/sysdeps/linux/or1k/bits/fcntl.h +++ b/libc/sysdeps/linux/or1k/bits/fcntl.h @@ -244,3 +244,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS + +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/or1k/bits/fenv.h b/libc/sysdeps/linux/or1k/bits/fenv.h new file mode 100644 index 000000000..4701946ff --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/fenv.h @@ -0,0 +1,84 @@ +/* Floating point environment, OpenRISC version. + Copyright (C) 2022-2025 Free Software Foundation, Inc. + + 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 + +#ifdef __or1k_hard_float__ +/* Define bits representing exceptions in the FPCSR status word. */ +enum + { + FE_OVERFLOW = +#define FE_OVERFLOW (1 << 3) + FE_OVERFLOW, + FE_UNDERFLOW = +#define FE_UNDERFLOW (1 << 4) + FE_UNDERFLOW, + FE_INEXACT = +#define FE_INEXACT (1 << 8) + FE_INEXACT, + FE_INVALID = +#define FE_INVALID (1 << 9) + FE_INVALID, + FE_DIVBYZERO = +#define FE_DIVBYZERO (1 << 11) + FE_DIVBYZERO, + }; + +/* All supported exceptions. */ +#define FE_ALL_EXCEPT \ + (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) + +/* Define bits representing rounding modes in the FPCSR Rmode field. */ +#define FE_TONEAREST (0x0 << 1) +#define FE_TOWARDZERO (0x1 << 1) +#define FE_UPWARD (0x2 << 1) +#define FE_DOWNWARD (0x3 << 1) + +#else + +/* In the soft-float case only rounding to nearest is supported, with + no exceptions. */ + +enum + { + __FE_UNDEFINED = -1, + + FE_TONEAREST = +# define FE_TONEAREST 0x0 + FE_TONEAREST + }; + +# define FE_ALL_EXCEPT 0 + +#endif /* __or1k_hard_float__ */ + +/* Type representing exception flags. */ +typedef unsigned int fexcept_t; + +/* Type representing floating-point environment. */ +typedef unsigned int fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((const fenv_t *) -1l) + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/or1k/fpu_control.h b/libc/sysdeps/linux/or1k/fpu_control.h new file mode 100644 index 000000000..9abde4f42 --- /dev/null +++ b/libc/sysdeps/linux/or1k/fpu_control.h @@ -0,0 +1,88 @@ +/* FPU control word bits. OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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 _FPU_CONTROL_H +#define _FPU_CONTROL_H + +#ifndef __or1k_hard_float__ + +# define _FPU_RESERVED 0xffffffff +# define _FPU_DEFAULT 0x00000000 +# define _FPU_GETCW(cw) (cw) = 0 +# define _FPU_SETCW(cw) (void) (cw) + +#else /* __or1k_hard_float__ */ + +/* Layout of FPCSR: + + The bits of the FPCSR are defined as follows, this should help + explain how the masks below have come to be. + + +-----------+----------------------------+-----+----+ + | 32 - 12 | 11 10 9 8 7 6 5 4 3 | 2-1 | 0 | + +-----------+----------------------------+-----+----+ + | Reserved | DZ IN IV IX Z QN SN UN OV | RM | EE | + +-----------+----------------------------+-----+----+ + + Exception flags: + + DZ - divide by zero flag. + IN - infinite flag. + IV - invalid flag. + IX - inexact flag. + Z - zero flag. + QN - qnan flag. + SN - snan flag. + UN - underflow flag. + OV - overflow flag. + + Rounding modes: + + The FPCSR bits 2-1 labeled above as RM specify the rounding mode. + + 00 - round to nearest + 01 - round to zero + 10 - round to positive infinity + 11 - round to negative infinity + + Enabling exceptions: + + EE - set to enable FPU exceptions. + + */ + +# define _FPU_RESERVED 0xfffff000 +/* Default: rounding to nearest with exceptions disabled. */ +# define _FPU_DEFAULT 0 +/* IEEE: Same as above with exceptions enabled. */ +# define _FPU_IEEE (_FPU_DEFAULT | 1) + +# define _FPU_FPCSR_RM_MASK (0x3 << 1) + +/* Macros for accessing the hardware control word. */ +# define _FPU_GETCW(cw) __asm__ volatile ("l.mfspr %0,r0,20" : "=r" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("l.mtspr r0,%0,20" : : "r" (cw)) + +#endif /* __or1k_hard_float__ */ + +/* Type of the control word. */ +typedef unsigned int fpu_control_t; + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif /* fpu_control.h */ diff --git a/libc/sysdeps/linux/powerpc/bits/fcntl.h b/libc/sysdeps/linux/powerpc/bits/fcntl.h index ef1beeca0..54e4894ec 100644 --- a/libc/sysdeps/linux/powerpc/bits/fcntl.h +++ b/libc/sysdeps/linux/powerpc/bits/fcntl.h @@ -245,3 +245,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/powerpc/bits/stat.h b/libc/sysdeps/linux/powerpc/bits/stat.h index 7494586b5..ce2ebf896 100644 --- a/libc/sysdeps/linux/powerpc/bits/stat.h +++ b/libc/sysdeps/linux/powerpc/bits/stat.h @@ -59,7 +59,7 @@ struct stat # else __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ # endif -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -99,7 +99,7 @@ struct stat64 __off64_t st_size; /* Size of file, in bytes. */ __blksize_t st_blksize; /* Optimal block size for I/O. */ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the diff --git a/libc/sysdeps/linux/riscv32/bits/fcntl.h b/libc/sysdeps/linux/riscv32/bits/fcntl.h index a9d7c84e0..fdfb1805d 100644 --- a/libc/sysdeps/linux/riscv32/bits/fcntl.h +++ b/libc/sysdeps/linux/riscv32/bits/fcntl.h @@ -229,3 +229,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS + +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/riscv32/bits/fenv.h b/libc/sysdeps/linux/riscv32/bits/fenv.h index a3f8031af..a6b828a76 100644 --- a/libc/sysdeps/linux/riscv32/bits/fenv.h +++ b/libc/sysdeps/linux/riscv32/bits/fenv.h @@ -64,10 +64,8 @@ typedef unsigned int fenv_t; /* If the default argument is used we use this value. */ #define FE_DFL_ENV ((__const fenv_t *) -1) -#if __GLIBC_USE (IEC_60559_BFP_EXT) /* Type representing floating-point control modes. */ typedef unsigned int femode_t; /* Default floating-point control modes. */ # define FE_DFL_MODE ((const femode_t *) -1L) -#endif diff --git a/libc/sysdeps/linux/riscv32/bits/shm.h b/libc/sysdeps/linux/riscv32/bits/shm.h index 8a11c7050..9190c562b 100644 --- a/libc/sysdeps/linux/riscv32/bits/shm.h +++ b/libc/sysdeps/linux/riscv32/bits/shm.h @@ -37,12 +37,18 @@ struct shmid_ds { struct ipc_perm shm_perm; /* operation permission struct */ size_t shm_segsz; /* size of segment in bytes */ +#if defined(__UCLIBC_USE_TIME64__) + __time_t shm_atime; + __time_t shm_dtime; + __time_t shm_ctime; +#else __time_t shm_atime; /* time of last shmat() */ unsigned long int __uclibc_unused1; __time_t shm_dtime; /* time of last shmdt() */ unsigned long int __uclibc_unused2; __time_t shm_ctime; /* time of last change by shmctl() */ unsigned long int __uclibc_unused3; +#endif __pid_t shm_cpid; /* pid of creator */ __pid_t shm_lpid; /* pid of last shmop */ shmatt_t shm_nattch; /* number of current attaches */ diff --git a/libc/sysdeps/linux/riscv32/crt1.S b/libc/sysdeps/linux/riscv32/crt1.S index 15aa0763c..5e33046d4 100644 --- a/libc/sysdeps/linux/riscv32/crt1.S +++ b/libc/sysdeps/linux/riscv32/crt1.S @@ -45,9 +45,6 @@ .globl _start .type _start,%function - .weak _init - .weak _fini - _start: call .Lload_gp mv a5, a0 /* rtld_fini. */ @@ -55,9 +52,9 @@ _start: la a0, main REG_L a1, 0(sp) /* argc. */ addi a2, sp, SZREG /* argv. */ + mv a3, zero + mv a4, zero andi sp, sp, ALMASK /* Align stack. */ - lla a3, _init - lla a4, _fini mv a6, sp /* stack_end. */ tail __uClibc_main@plt diff --git a/libc/sysdeps/linux/riscv32/getcontext.S b/libc/sysdeps/linux/riscv32/getcontext.S deleted file mode 100644 index 0b9e7c2d3..000000000 --- a/libc/sysdeps/linux/riscv32/getcontext.S +++ /dev/null @@ -1,74 +0,0 @@ -/* Save current context. - Copyright (C) 2009-2018 Free Software Foundation, Inc. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "ucontext-macros.h" - -/* int getcontext (ucontext_t *ucp) */ - - .text -LEAF (getcontext) - SAVE_INT_REG (ra, 0, a0) - SAVE_INT_REG (ra, 1, a0) - SAVE_INT_REG (sp, 2, a0) - SAVE_INT_REG (s0, 8, a0) - SAVE_INT_REG (s1, 9, a0) - SAVE_INT_REG (x0, 10, a0) /* return 0 by overwriting a0. */ - SAVE_INT_REG (s2, 18, a0) - SAVE_INT_REG (s3, 19, a0) - SAVE_INT_REG (s4, 20, a0) - SAVE_INT_REG (s5, 21, a0) - SAVE_INT_REG (s6, 22, a0) - SAVE_INT_REG (s7, 23, a0) - SAVE_INT_REG (s8, 24, a0) - SAVE_INT_REG (s9, 25, a0) - SAVE_INT_REG (s10, 26, a0) - SAVE_INT_REG (s11, 27, a0) - -#ifndef __riscv_float_abi_soft - frsr a1 - - SAVE_FP_REG (fs0, 8, a0) - SAVE_FP_REG (fs1, 9, a0) - SAVE_FP_REG (fs2, 18, a0) - SAVE_FP_REG (fs3, 19, a0) - SAVE_FP_REG (fs4, 20, a0) - SAVE_FP_REG (fs5, 21, a0) - SAVE_FP_REG (fs6, 22, a0) - SAVE_FP_REG (fs7, 23, a0) - SAVE_FP_REG (fs8, 24, a0) - SAVE_FP_REG (fs9, 25, a0) - SAVE_FP_REG (fs10, 26, a0) - SAVE_FP_REG (fs11, 27, a0) - - sw a1, MCONTEXT_FSR(a0) -#endif /* __riscv_float_abi_soft */ - -/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ - li a3, _NSIG8 - add a2, a0, UCONTEXT_SIGMASK - mv a1, zero - li a0, SIG_BLOCK - - li a7, SYS_ify (rt_sigprocmask) - scall - bltz a0, 99f - - ret - -99: j __syscall_error - -PSEUDO_END (getcontext) diff --git a/libc/sysdeps/linux/riscv32/jmpbuf-unwind.h b/libc/sysdeps/linux/riscv32/jmpbuf-unwind.h index 2e5f37f10..fb5d65ddd 100644 --- a/libc/sysdeps/linux/riscv32/jmpbuf-unwind.h +++ b/libc/sysdeps/linux/riscv32/jmpbuf-unwind.h @@ -23,8 +23,8 @@ /* Test if longjmp to JMPBUF would unwind the frame containing a local variable at ADDRESS. */ -#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \ - ((void *) (address) < (void *) demangle ((jmpbuf)[0].__sp)) +#define _JMPBUF_UNWINDS(jmpbuf, address) \ + ((void *) (address) < (void *) ((jmpbuf)[0].__sp)) #define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) @@ -33,9 +33,6 @@ static inline uintptr_t __attribute__ ((unused)) _jmpbuf_sp (__jmp_buf regs) { uintptr_t sp = regs[0].__sp; -#ifdef PTR_DEMANGLE - PTR_DEMANGLE (sp); -#endif return sp; } diff --git a/libc/sysdeps/linux/riscv32/setcontext.S b/libc/sysdeps/linux/riscv32/setcontext.S deleted file mode 100644 index 15cc17bd8..000000000 --- a/libc/sysdeps/linux/riscv32/setcontext.S +++ /dev/null @@ -1,112 +0,0 @@ -/* Set current context. - Copyright (C) 2009-2018 Free Software Foundation, Inc. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "ucontext-macros.h" - -/* int __setcontext (const ucontext_t *ucp) - - Restores the machine context in UCP and thereby resumes execution - in that context. - - This implementation is intended to be used for *synchronous* context - switches only. Therefore, it does not have to restore anything - other than the PRESERVED state. */ - - .text -LEAF (setcontext) - - mv t0, a0 /* Save ucp into t0. */ - -/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */ - li a3, _NSIG8 - mv a2, zero - add a1, a0, UCONTEXT_SIGMASK - li a0, SIG_SETMASK - - li a7, SYS_ify (rt_sigprocmask) - scall - - bltz a0, 99f - - cfi_def_cfa (t0, 0) - -#ifndef __riscv_float_abi_soft - lw t1, MCONTEXT_FSR(t0) - - RESTORE_FP_REG_CFI (fs0, 8, t0) - RESTORE_FP_REG_CFI (fs1, 9, t0) - RESTORE_FP_REG_CFI (fs2, 18, t0) - RESTORE_FP_REG_CFI (fs3, 19, t0) - RESTORE_FP_REG_CFI (fs4, 20, t0) - RESTORE_FP_REG_CFI (fs5, 21, t0) - RESTORE_FP_REG_CFI (fs6, 22, t0) - RESTORE_FP_REG_CFI (fs7, 23, t0) - RESTORE_FP_REG_CFI (fs8, 24, t0) - RESTORE_FP_REG_CFI (fs9, 25, t0) - RESTORE_FP_REG_CFI (fs10, 26, t0) - RESTORE_FP_REG_CFI (fs11, 27, t0) - - fssr t1 -#endif /* __riscv_float_abi_soft */ - - /* Note the contents of argument registers will be random - unless makecontext() has been called. */ - RESTORE_INT_REG (t1, 0, t0) - RESTORE_INT_REG_CFI (ra, 1, t0) - RESTORE_INT_REG (sp, 2, t0) - RESTORE_INT_REG_CFI (s0, 8, t0) - RESTORE_INT_REG_CFI (s1, 9, t0) - RESTORE_INT_REG (a0, 10, t0) - RESTORE_INT_REG (a1, 11, t0) - RESTORE_INT_REG (a2, 12, t0) - RESTORE_INT_REG (a3, 13, t0) - RESTORE_INT_REG (a4, 14, t0) - RESTORE_INT_REG (a5, 15, t0) - RESTORE_INT_REG (a6, 16, t0) - RESTORE_INT_REG (a7, 17, t0) - RESTORE_INT_REG_CFI (s2, 18, t0) - RESTORE_INT_REG_CFI (s3, 19, t0) - RESTORE_INT_REG_CFI (s4, 20, t0) - RESTORE_INT_REG_CFI (s5, 21, t0) - RESTORE_INT_REG_CFI (s6, 22, t0) - RESTORE_INT_REG_CFI (s7, 23, t0) - RESTORE_INT_REG_CFI (s8, 24, t0) - RESTORE_INT_REG_CFI (s9, 25, t0) - RESTORE_INT_REG_CFI (s10, 26, t0) - RESTORE_INT_REG_CFI (s11, 27, t0) - - jr t1 - -99: j __syscall_error - -PSEUDO_END (setcontext) - -LEAF (start_context) - - /* Terminate call stack by noting ra == 0. Happily, s0 == 0 here. */ - cfi_register (ra, s0) - - /* Call the function passed to makecontext. */ - jalr s1 - - /* Invoke subsequent context if present, else exit(0). */ - mv a0, s2 - beqz s2, 1f - jal setcontext -1: j exit - -PSEUDO_END (start_context) diff --git a/libc/sysdeps/linux/riscv32/swapcontext.S b/libc/sysdeps/linux/riscv32/swapcontext.S deleted file mode 100644 index f5e12b2db..000000000 --- a/libc/sysdeps/linux/riscv32/swapcontext.S +++ /dev/null @@ -1,122 +0,0 @@ -/* Save and set current context. - Copyright (C) 2009-2018 Free Software Foundation, Inc. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "ucontext-macros.h" - -/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ - -LEAF (swapcontext) - mv t0, a1 /* Save ucp into t0. */ - - SAVE_INT_REG (ra, 0, a0) - SAVE_INT_REG (ra, 1, a0) - SAVE_INT_REG (sp, 2, a0) - SAVE_INT_REG (s0, 8, a0) - SAVE_INT_REG (s1, 9, a0) - SAVE_INT_REG (x0, 10, a0) /* return 0 by overwriting a0. */ - SAVE_INT_REG (s2, 18, a0) - SAVE_INT_REG (s3, 19, a0) - SAVE_INT_REG (s4, 20, a0) - SAVE_INT_REG (s5, 21, a0) - SAVE_INT_REG (s6, 22, a0) - SAVE_INT_REG (s7, 23, a0) - SAVE_INT_REG (s8, 24, a0) - SAVE_INT_REG (s9, 25, a0) - SAVE_INT_REG (s10, 26, a0) - SAVE_INT_REG (s11, 27, a0) - -#ifndef __riscv_float_abi_soft - frsr a1 - - SAVE_FP_REG (fs0, 8, a0) - SAVE_FP_REG (fs1, 9, a0) - SAVE_FP_REG (fs2, 18, a0) - SAVE_FP_REG (fs3, 19, a0) - SAVE_FP_REG (fs4, 20, a0) - SAVE_FP_REG (fs5, 21, a0) - SAVE_FP_REG (fs6, 22, a0) - SAVE_FP_REG (fs7, 23, a0) - SAVE_FP_REG (fs8, 24, a0) - SAVE_FP_REG (fs9, 25, a0) - SAVE_FP_REG (fs10, 26, a0) - SAVE_FP_REG (fs11, 27, a0) - - sw a1, MCONTEXT_FSR(a0) -#endif /* __riscv_float_abi_soft */ - -/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */ - li a3, _NSIG8 - add a2, a0, UCONTEXT_SIGMASK - add a1, t0, UCONTEXT_SIGMASK - li a0, SIG_SETMASK - - li a7, SYS_ify (rt_sigprocmask) - scall - - bltz a0, 99f - -#ifndef __riscv_float_abi_soft - lw t1, MCONTEXT_FSR(t0) - - RESTORE_FP_REG (fs0, 8, t0) - RESTORE_FP_REG (fs1, 9, t0) - RESTORE_FP_REG (fs2, 18, t0) - RESTORE_FP_REG (fs3, 19, t0) - RESTORE_FP_REG (fs4, 20, t0) - RESTORE_FP_REG (fs5, 21, t0) - RESTORE_FP_REG (fs6, 22, t0) - RESTORE_FP_REG (fs7, 23, t0) - RESTORE_FP_REG (fs8, 24, t0) - RESTORE_FP_REG (fs9, 25, t0) - RESTORE_FP_REG (fs10, 26, t0) - RESTORE_FP_REG (fs11, 27, t0) - - fssr t1 -#endif /* __riscv_float_abi_soft */ - - /* Note the contents of argument registers will be random - unless makecontext() has been called. */ - RESTORE_INT_REG (t1, 0, t0) - RESTORE_INT_REG (ra, 1, t0) - RESTORE_INT_REG (sp, 2, t0) - RESTORE_INT_REG (s0, 8, t0) - RESTORE_INT_REG (s1, 9, t0) - RESTORE_INT_REG (a0, 10, t0) - RESTORE_INT_REG (a1, 11, t0) - RESTORE_INT_REG (a2, 12, t0) - RESTORE_INT_REG (a3, 13, t0) - RESTORE_INT_REG (a4, 14, t0) - RESTORE_INT_REG (a5, 15, t0) - RESTORE_INT_REG (a6, 16, t0) - RESTORE_INT_REG (a7, 17, t0) - RESTORE_INT_REG (s2, 18, t0) - RESTORE_INT_REG (s3, 19, t0) - RESTORE_INT_REG (s4, 20, t0) - RESTORE_INT_REG (s5, 21, t0) - RESTORE_INT_REG (s6, 22, t0) - RESTORE_INT_REG (s7, 23, t0) - RESTORE_INT_REG (s8, 24, t0) - RESTORE_INT_REG (s9, 25, t0) - RESTORE_INT_REG (s10, 26, t0) - RESTORE_INT_REG (s11, 27, t0) - - jr t1 - - -99: j __syscall_error - -PSEUDO_END (swapcontext) diff --git a/libc/sysdeps/linux/riscv32/sys/ucontext.h b/libc/sysdeps/linux/riscv32/sys/ucontext.h index 2893ff359..308ccb8c2 100644 --- a/libc/sysdeps/linux/riscv32/sys/ucontext.h +++ b/libc/sysdeps/linux/riscv32/sys/ucontext.h @@ -83,10 +83,10 @@ typedef struct mcontext_t } mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { unsigned long int __uc_flags; - struct ucontext_t *uc_link; + struct ucontext *uc_link; stack_t uc_stack; sigset_t uc_sigmask; /* There's some padding here to allow sigset_t to be expanded in the diff --git a/libc/sysdeps/linux/riscv64/bits/fcntl.h b/libc/sysdeps/linux/riscv64/bits/fcntl.h index a9d7c84e0..fdfb1805d 100644 --- a/libc/sysdeps/linux/riscv64/bits/fcntl.h +++ b/libc/sysdeps/linux/riscv64/bits/fcntl.h @@ -229,3 +229,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS + +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/riscv64/bits/fenv.h b/libc/sysdeps/linux/riscv64/bits/fenv.h index a3f8031af..a6b828a76 100644 --- a/libc/sysdeps/linux/riscv64/bits/fenv.h +++ b/libc/sysdeps/linux/riscv64/bits/fenv.h @@ -64,10 +64,8 @@ typedef unsigned int fenv_t; /* If the default argument is used we use this value. */ #define FE_DFL_ENV ((__const fenv_t *) -1) -#if __GLIBC_USE (IEC_60559_BFP_EXT) /* Type representing floating-point control modes. */ typedef unsigned int femode_t; /* Default floating-point control modes. */ # define FE_DFL_MODE ((const femode_t *) -1L) -#endif diff --git a/libc/sysdeps/linux/riscv64/bits/shm.h b/libc/sysdeps/linux/riscv64/bits/shm.h index 8a11c7050..bfb603499 100644 --- a/libc/sysdeps/linux/riscv64/bits/shm.h +++ b/libc/sysdeps/linux/riscv64/bits/shm.h @@ -38,16 +38,13 @@ struct shmid_ds struct ipc_perm shm_perm; /* operation permission struct */ size_t shm_segsz; /* size of segment in bytes */ __time_t shm_atime; /* time of last shmat() */ - unsigned long int __uclibc_unused1; __time_t shm_dtime; /* time of last shmdt() */ - unsigned long int __uclibc_unused2; __time_t shm_ctime; /* time of last change by shmctl() */ - unsigned long int __uclibc_unused3; __pid_t shm_cpid; /* pid of creator */ __pid_t shm_lpid; /* pid of last shmop */ shmatt_t shm_nattch; /* number of current attaches */ - unsigned long int __uclibc_unused4; - unsigned long int __uclibc_unused5; + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; }; #ifdef __USE_MISC diff --git a/libc/sysdeps/linux/riscv64/crt1.S b/libc/sysdeps/linux/riscv64/crt1.S index 15aa0763c..5e33046d4 100644 --- a/libc/sysdeps/linux/riscv64/crt1.S +++ b/libc/sysdeps/linux/riscv64/crt1.S @@ -45,9 +45,6 @@ .globl _start .type _start,%function - .weak _init - .weak _fini - _start: call .Lload_gp mv a5, a0 /* rtld_fini. */ @@ -55,9 +52,9 @@ _start: la a0, main REG_L a1, 0(sp) /* argc. */ addi a2, sp, SZREG /* argv. */ + mv a3, zero + mv a4, zero andi sp, sp, ALMASK /* Align stack. */ - lla a3, _init - lla a4, _fini mv a6, sp /* stack_end. */ tail __uClibc_main@plt diff --git a/libc/sysdeps/linux/riscv64/getcontext.S b/libc/sysdeps/linux/riscv64/getcontext.S deleted file mode 100644 index 0b9e7c2d3..000000000 --- a/libc/sysdeps/linux/riscv64/getcontext.S +++ /dev/null @@ -1,74 +0,0 @@ -/* Save current context. - Copyright (C) 2009-2018 Free Software Foundation, Inc. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "ucontext-macros.h" - -/* int getcontext (ucontext_t *ucp) */ - - .text -LEAF (getcontext) - SAVE_INT_REG (ra, 0, a0) - SAVE_INT_REG (ra, 1, a0) - SAVE_INT_REG (sp, 2, a0) - SAVE_INT_REG (s0, 8, a0) - SAVE_INT_REG (s1, 9, a0) - SAVE_INT_REG (x0, 10, a0) /* return 0 by overwriting a0. */ - SAVE_INT_REG (s2, 18, a0) - SAVE_INT_REG (s3, 19, a0) - SAVE_INT_REG (s4, 20, a0) - SAVE_INT_REG (s5, 21, a0) - SAVE_INT_REG (s6, 22, a0) - SAVE_INT_REG (s7, 23, a0) - SAVE_INT_REG (s8, 24, a0) - SAVE_INT_REG (s9, 25, a0) - SAVE_INT_REG (s10, 26, a0) - SAVE_INT_REG (s11, 27, a0) - -#ifndef __riscv_float_abi_soft - frsr a1 - - SAVE_FP_REG (fs0, 8, a0) - SAVE_FP_REG (fs1, 9, a0) - SAVE_FP_REG (fs2, 18, a0) - SAVE_FP_REG (fs3, 19, a0) - SAVE_FP_REG (fs4, 20, a0) - SAVE_FP_REG (fs5, 21, a0) - SAVE_FP_REG (fs6, 22, a0) - SAVE_FP_REG (fs7, 23, a0) - SAVE_FP_REG (fs8, 24, a0) - SAVE_FP_REG (fs9, 25, a0) - SAVE_FP_REG (fs10, 26, a0) - SAVE_FP_REG (fs11, 27, a0) - - sw a1, MCONTEXT_FSR(a0) -#endif /* __riscv_float_abi_soft */ - -/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ - li a3, _NSIG8 - add a2, a0, UCONTEXT_SIGMASK - mv a1, zero - li a0, SIG_BLOCK - - li a7, SYS_ify (rt_sigprocmask) - scall - bltz a0, 99f - - ret - -99: j __syscall_error - -PSEUDO_END (getcontext) diff --git a/libc/sysdeps/linux/riscv64/setcontext.S b/libc/sysdeps/linux/riscv64/setcontext.S deleted file mode 100644 index 15cc17bd8..000000000 --- a/libc/sysdeps/linux/riscv64/setcontext.S +++ /dev/null @@ -1,112 +0,0 @@ -/* Set current context. - Copyright (C) 2009-2018 Free Software Foundation, Inc. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "ucontext-macros.h" - -/* int __setcontext (const ucontext_t *ucp) - - Restores the machine context in UCP and thereby resumes execution - in that context. - - This implementation is intended to be used for *synchronous* context - switches only. Therefore, it does not have to restore anything - other than the PRESERVED state. */ - - .text -LEAF (setcontext) - - mv t0, a0 /* Save ucp into t0. */ - -/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */ - li a3, _NSIG8 - mv a2, zero - add a1, a0, UCONTEXT_SIGMASK - li a0, SIG_SETMASK - - li a7, SYS_ify (rt_sigprocmask) - scall - - bltz a0, 99f - - cfi_def_cfa (t0, 0) - -#ifndef __riscv_float_abi_soft - lw t1, MCONTEXT_FSR(t0) - - RESTORE_FP_REG_CFI (fs0, 8, t0) - RESTORE_FP_REG_CFI (fs1, 9, t0) - RESTORE_FP_REG_CFI (fs2, 18, t0) - RESTORE_FP_REG_CFI (fs3, 19, t0) - RESTORE_FP_REG_CFI (fs4, 20, t0) - RESTORE_FP_REG_CFI (fs5, 21, t0) - RESTORE_FP_REG_CFI (fs6, 22, t0) - RESTORE_FP_REG_CFI (fs7, 23, t0) - RESTORE_FP_REG_CFI (fs8, 24, t0) - RESTORE_FP_REG_CFI (fs9, 25, t0) - RESTORE_FP_REG_CFI (fs10, 26, t0) - RESTORE_FP_REG_CFI (fs11, 27, t0) - - fssr t1 -#endif /* __riscv_float_abi_soft */ - - /* Note the contents of argument registers will be random - unless makecontext() has been called. */ - RESTORE_INT_REG (t1, 0, t0) - RESTORE_INT_REG_CFI (ra, 1, t0) - RESTORE_INT_REG (sp, 2, t0) - RESTORE_INT_REG_CFI (s0, 8, t0) - RESTORE_INT_REG_CFI (s1, 9, t0) - RESTORE_INT_REG (a0, 10, t0) - RESTORE_INT_REG (a1, 11, t0) - RESTORE_INT_REG (a2, 12, t0) - RESTORE_INT_REG (a3, 13, t0) - RESTORE_INT_REG (a4, 14, t0) - RESTORE_INT_REG (a5, 15, t0) - RESTORE_INT_REG (a6, 16, t0) - RESTORE_INT_REG (a7, 17, t0) - RESTORE_INT_REG_CFI (s2, 18, t0) - RESTORE_INT_REG_CFI (s3, 19, t0) - RESTORE_INT_REG_CFI (s4, 20, t0) - RESTORE_INT_REG_CFI (s5, 21, t0) - RESTORE_INT_REG_CFI (s6, 22, t0) - RESTORE_INT_REG_CFI (s7, 23, t0) - RESTORE_INT_REG_CFI (s8, 24, t0) - RESTORE_INT_REG_CFI (s9, 25, t0) - RESTORE_INT_REG_CFI (s10, 26, t0) - RESTORE_INT_REG_CFI (s11, 27, t0) - - jr t1 - -99: j __syscall_error - -PSEUDO_END (setcontext) - -LEAF (start_context) - - /* Terminate call stack by noting ra == 0. Happily, s0 == 0 here. */ - cfi_register (ra, s0) - - /* Call the function passed to makecontext. */ - jalr s1 - - /* Invoke subsequent context if present, else exit(0). */ - mv a0, s2 - beqz s2, 1f - jal setcontext -1: j exit - -PSEUDO_END (start_context) diff --git a/libc/sysdeps/linux/riscv64/swapcontext.S b/libc/sysdeps/linux/riscv64/swapcontext.S deleted file mode 100644 index f5e12b2db..000000000 --- a/libc/sysdeps/linux/riscv64/swapcontext.S +++ /dev/null @@ -1,122 +0,0 @@ -/* Save and set current context. - Copyright (C) 2009-2018 Free Software Foundation, Inc. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "ucontext-macros.h" - -/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ - -LEAF (swapcontext) - mv t0, a1 /* Save ucp into t0. */ - - SAVE_INT_REG (ra, 0, a0) - SAVE_INT_REG (ra, 1, a0) - SAVE_INT_REG (sp, 2, a0) - SAVE_INT_REG (s0, 8, a0) - SAVE_INT_REG (s1, 9, a0) - SAVE_INT_REG (x0, 10, a0) /* return 0 by overwriting a0. */ - SAVE_INT_REG (s2, 18, a0) - SAVE_INT_REG (s3, 19, a0) - SAVE_INT_REG (s4, 20, a0) - SAVE_INT_REG (s5, 21, a0) - SAVE_INT_REG (s6, 22, a0) - SAVE_INT_REG (s7, 23, a0) - SAVE_INT_REG (s8, 24, a0) - SAVE_INT_REG (s9, 25, a0) - SAVE_INT_REG (s10, 26, a0) - SAVE_INT_REG (s11, 27, a0) - -#ifndef __riscv_float_abi_soft - frsr a1 - - SAVE_FP_REG (fs0, 8, a0) - SAVE_FP_REG (fs1, 9, a0) - SAVE_FP_REG (fs2, 18, a0) - SAVE_FP_REG (fs3, 19, a0) - SAVE_FP_REG (fs4, 20, a0) - SAVE_FP_REG (fs5, 21, a0) - SAVE_FP_REG (fs6, 22, a0) - SAVE_FP_REG (fs7, 23, a0) - SAVE_FP_REG (fs8, 24, a0) - SAVE_FP_REG (fs9, 25, a0) - SAVE_FP_REG (fs10, 26, a0) - SAVE_FP_REG (fs11, 27, a0) - - sw a1, MCONTEXT_FSR(a0) -#endif /* __riscv_float_abi_soft */ - -/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */ - li a3, _NSIG8 - add a2, a0, UCONTEXT_SIGMASK - add a1, t0, UCONTEXT_SIGMASK - li a0, SIG_SETMASK - - li a7, SYS_ify (rt_sigprocmask) - scall - - bltz a0, 99f - -#ifndef __riscv_float_abi_soft - lw t1, MCONTEXT_FSR(t0) - - RESTORE_FP_REG (fs0, 8, t0) - RESTORE_FP_REG (fs1, 9, t0) - RESTORE_FP_REG (fs2, 18, t0) - RESTORE_FP_REG (fs3, 19, t0) - RESTORE_FP_REG (fs4, 20, t0) - RESTORE_FP_REG (fs5, 21, t0) - RESTORE_FP_REG (fs6, 22, t0) - RESTORE_FP_REG (fs7, 23, t0) - RESTORE_FP_REG (fs8, 24, t0) - RESTORE_FP_REG (fs9, 25, t0) - RESTORE_FP_REG (fs10, 26, t0) - RESTORE_FP_REG (fs11, 27, t0) - - fssr t1 -#endif /* __riscv_float_abi_soft */ - - /* Note the contents of argument registers will be random - unless makecontext() has been called. */ - RESTORE_INT_REG (t1, 0, t0) - RESTORE_INT_REG (ra, 1, t0) - RESTORE_INT_REG (sp, 2, t0) - RESTORE_INT_REG (s0, 8, t0) - RESTORE_INT_REG (s1, 9, t0) - RESTORE_INT_REG (a0, 10, t0) - RESTORE_INT_REG (a1, 11, t0) - RESTORE_INT_REG (a2, 12, t0) - RESTORE_INT_REG (a3, 13, t0) - RESTORE_INT_REG (a4, 14, t0) - RESTORE_INT_REG (a5, 15, t0) - RESTORE_INT_REG (a6, 16, t0) - RESTORE_INT_REG (a7, 17, t0) - RESTORE_INT_REG (s2, 18, t0) - RESTORE_INT_REG (s3, 19, t0) - RESTORE_INT_REG (s4, 20, t0) - RESTORE_INT_REG (s5, 21, t0) - RESTORE_INT_REG (s6, 22, t0) - RESTORE_INT_REG (s7, 23, t0) - RESTORE_INT_REG (s8, 24, t0) - RESTORE_INT_REG (s9, 25, t0) - RESTORE_INT_REG (s10, 26, t0) - RESTORE_INT_REG (s11, 27, t0) - - jr t1 - - -99: j __syscall_error - -PSEUDO_END (swapcontext) diff --git a/libc/sysdeps/linux/riscv64/sys/ucontext.h b/libc/sysdeps/linux/riscv64/sys/ucontext.h index 2893ff359..308ccb8c2 100644 --- a/libc/sysdeps/linux/riscv64/sys/ucontext.h +++ b/libc/sysdeps/linux/riscv64/sys/ucontext.h @@ -83,10 +83,10 @@ typedef struct mcontext_t } mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { unsigned long int __uc_flags; - struct ucontext_t *uc_link; + struct ucontext *uc_link; stack_t uc_stack; sigset_t uc_sigmask; /* There's some padding here to allow sigset_t to be expanded in the diff --git a/libc/sysdeps/linux/sh/bits/fcntl.h b/libc/sysdeps/linux/sh/bits/fcntl.h index 0d687f04f..4ae682425 100644 --- a/libc/sysdeps/linux/sh/bits/fcntl.h +++ b/libc/sysdeps/linux/sh/bits/fcntl.h @@ -245,3 +245,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/sh/bits/fenv.h b/libc/sysdeps/linux/sh/bits/fenv.h index 38c303ff2..349e7ddde 100644 --- a/libc/sysdeps/linux/sh/bits/fenv.h +++ b/libc/sysdeps/linux/sh/bits/fenv.h @@ -1,5 +1,4 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* Copyright (C) 1999-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -13,7 +12,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ #ifndef _FENV_H # error "Never use <bits/fenv.h> directly; include <fenv.h> instead." @@ -24,34 +23,39 @@ of the appropriate bits in the FPU control word. */ enum { - FE_INEXACT = 0x04, -#define FE_INEXACT FE_INEXACT - FE_UNDERFLOW = 0x08, -#define FE_UNDERFLOW FE_UNDERFLOW - FE_OVERFLOW = 0x10, -#define FE_OVERFLOW FE_OVERFLOW - FE_DIVBYZERO = 0x20, -#define FE_DIVBYZERO FE_DIVBYZERO - FE_INVALID = 0x40, -#define FE_INVALID FE_INVALID + FE_INEXACT = +#define FE_INEXACT 0x04 + FE_INEXACT, + FE_UNDERFLOW = +#define FE_UNDERFLOW 0x08 + FE_UNDERFLOW, + FE_OVERFLOW = +#define FE_OVERFLOW 0x10 + FE_OVERFLOW, + FE_DIVBYZERO = +#define FE_DIVBYZERO 0x20 + FE_DIVBYZERO, + FE_INVALID = +#define FE_INVALID 0x40 + FE_INVALID, }; #define FE_ALL_EXCEPT \ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) -/* The SH FPU supports all of the four defined rounding modes. We - use again the bit positions in the FPU control word as the values - for the appropriate macros. */ +/* The SH FPU supports two of the four defined rounding modes: round to nearest + and round to zero. We use again the bit positions in the FPU control word + as the values for the appropriate macros. */ enum { - FE_TONEAREST = 0x0, -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = 0x1, -#define FE_TOWARDZERO FE_TOWARDZERO - FE_UPWARD = 0x2, -#define FE_UPWARD FE_UPWARD - FE_DOWNWARD = 0x3 -#define FE_DOWNWARD FE_DOWNWARD + __FE_UNDEFINED = -1, + + FE_TONEAREST = +#define FE_TONEAREST 0x0 + FE_TONEAREST, + FE_TOWARDZERO = +#define FE_TOWARDZERO 0x1 + FE_TOWARDZERO, }; @@ -68,4 +72,10 @@ typedef struct fenv_t; /* If the default argument is used we use this value. */ -#define FE_DFL_ENV ((fenv_t *) -1) +#define FE_DFL_ENV ((const fenv_t *) -1) + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/sh/fpu_control.h b/libc/sysdeps/linux/sh/fpu_control.h index 8143041fe..d5f401f91 100644 --- a/libc/sysdeps/linux/sh/fpu_control.h +++ b/libc/sysdeps/linux/sh/fpu_control.h @@ -1,6 +1,5 @@ /* FPU control word definitions. SH version. - Copyright (C) 1999, 2000, 2009 Free Software Foundation, Inc. - This file is part of the GNU C Library. + Copyright (C) 1999-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -14,14 +13,23 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ #ifndef _FPU_CONTROL_H #define _FPU_CONTROL_H -#ifndef __SH4__ -#error This file is only correct for sh4 -#endif +#if !defined(__SH_FPU_ANY__) + +#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 + +#include <features.h> /* masking of interrupts */ #define _FPU_MASK_VM 0x0800 /* Invalid operation */ @@ -48,16 +56,20 @@ typedef unsigned int fpu_control_t; #define _FPU_GETCW(cw) __asm__ ("sts fpscr,%0" : "=r" (cw)) #if defined __GNUC__ -/* GCC provides this function */ +__BEGIN_DECLS + +/* GCC provides this function. */ extern void __set_fpscr (unsigned long); #define _FPU_SETCW(cw) __set_fpscr ((cw)) #else #define _FPU_SETCW(cw) __asm__ ("lds %0,fpscr" : : "r" (cw)) #endif -#if 0 /* Default control word set at startup. */ extern fpu_control_t __fpu_control; -#endif + +__END_DECLS + +#endif /* __SH_FPU_ANY__ */ #endif /* _FPU_CONTROL_H */ diff --git a/libc/sysdeps/linux/sparc/Makefile.arch b/libc/sysdeps/linux/sparc/Makefile.arch index d34624f36..c9529b344 100644 --- a/libc/sysdeps/linux/sparc/Makefile.arch +++ b/libc/sysdeps/linux/sparc/Makefile.arch @@ -6,7 +6,7 @@ # CSRC-y := brk.c __syscall_error.c sigaction.c -SSRC-y := __longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S \ +SSRC-y := __longjmp.S setjmp.S sigreturn_stub.S bsd-setjmp.S bsd-_setjmp.S \ syscall.S urem.S udiv.S umul.S sdiv.S rem.S pipe.S fork.S vfork.S clone.S CSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.c diff --git a/libc/sysdeps/linux/sparc/bits/fcntl.h b/libc/sysdeps/linux/sparc/bits/fcntl.h index 935495937..35224cdb3 100644 --- a/libc/sysdeps/linux/sparc/bits/fcntl.h +++ b/libc/sysdeps/linux/sparc/bits/fcntl.h @@ -252,3 +252,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/sparc/bits/fenv.h b/libc/sysdeps/linux/sparc/bits/fenv.h index 79ab8cefa..83b32cc51 100644 --- a/libc/sysdeps/linux/sparc/bits/fenv.h +++ b/libc/sysdeps/linux/sparc/bits/fenv.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1997-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -12,26 +12,34 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ #ifndef _FENV_H # error "Never use <bits/fenv.h> directly; include <fenv.h> instead." #endif +#include <bits/wordsize.h> + + /* Define bits representing the exception. We use the bit positions of the appropriate accrued exception bits from the FSR. */ enum { - FE_INVALID = (1 << 9), -#define FE_INVALID FE_INVALID - FE_OVERFLOW = (1 << 8), -#define FE_OVERFLOW FE_OVERFLOW - FE_UNDERFLOW = (1 << 7), -#define FE_UNDERFLOW FE_UNDERFLOW - FE_DIVBYZERO = (1 << 6), -#define FE_DIVBYZERO FE_DIVBYZERO - FE_INEXACT = (1 << 5) -#define FE_INEXACT FE_INEXACT + FE_INVALID = +#define FE_INVALID (1 << 9) + FE_INVALID, + FE_OVERFLOW = +#define FE_OVERFLOW (1 << 8) + FE_OVERFLOW, + FE_UNDERFLOW = +#define FE_UNDERFLOW (1 << 7) + FE_UNDERFLOW, + FE_DIVBYZERO = +#define FE_DIVBYZERO (1 << 6) + FE_DIVBYZERO, + FE_INEXACT = +#define FE_INEXACT (1 << 5) + FE_INEXACT }; #define FE_ALL_EXCEPT \ @@ -42,14 +50,18 @@ enum for the appropriate macros. */ enum { - FE_TONEAREST = (0U << 30), -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = (1U << 30), -#define FE_TOWARDZERO FE_TOWARDZERO - FE_UPWARD = (2U << 30), -#define FE_UPWARD FE_UPWARD - FE_DOWNWARD = (3U << 30) -#define FE_DOWNWARD FE_DOWNWARD + FE_TONEAREST = +#define FE_TONEAREST (0 << 30) + FE_TONEAREST, + FE_TOWARDZERO = +#define FE_TOWARDZERO (1 << 30) + FE_TOWARDZERO, + FE_UPWARD = +#define FE_UPWARD (-0x7fffffff - 1) /* (2 << 30) */ + FE_UPWARD, + FE_DOWNWARD = +#define FE_DOWNWARD (-0x40000000) /* (3 << 30) */ + FE_DOWNWARD }; #define __FE_ROUND_MASK (3U << 30) @@ -70,6 +82,8 @@ typedef unsigned long int fenv_t; # define FE_NOMASK_ENV ((const fenv_t *) -2) #endif -/* For internal use only: access the fp state register. */ -#define __fenv_stfsr(X) __asm__ ("st %%fsr,%0" : "=m" (X)) -#define __fenv_ldfsr(X) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (X)) +/* Type representing floating-point control modes. */ +typedef unsigned long int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/sparc/bits/stat.h b/libc/sysdeps/linux/sparc/bits/stat.h index b88885fe2..0fbef8b3f 100644 --- a/libc/sysdeps/linux/sparc/bits/stat.h +++ b/libc/sysdeps/linux/sparc/bits/stat.h @@ -53,7 +53,7 @@ struct stat #else __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ #endif -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -93,7 +93,7 @@ struct stat64 __blksize_t st_blksize; /* Optimal block size for I/O. */ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the diff --git a/libc/sysdeps/linux/sparc/fpu_control.h b/libc/sysdeps/linux/sparc/fpu_control.h index 57f1dbb67..542f9fb1b 100644 --- a/libc/sysdeps/linux/sparc/fpu_control.h +++ b/libc/sysdeps/linux/sparc/fpu_control.h @@ -1,6 +1,5 @@ /* FPU control word bits. SPARC version. - Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. - Contributed by Miguel de Icaza + Copyright (C) 1997-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -14,13 +13,14 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ #ifndef _FPU_CONTROL_H #define _FPU_CONTROL_H 1 #include <features.h> +#include <bits/wordsize.h> /* masking of interrupts */ #define _FPU_MASK_IM 0x08000000 @@ -41,7 +41,7 @@ #define _FPU_RC_ZERO 0x40000000 #define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */ -#define _FPU_RESERVED 0x30300000 /* Reserved bits in cw */ +#define _FPU_RESERVED 0x303e0000 /* Reserved bits in cw */ /* Now two recommended cw */ @@ -56,12 +56,20 @@ /* Type of the control word. */ typedef unsigned long int fpu_control_t; -#define _FPU_GETCW(cw) __asm__ ("st %%fsr,%0" : "=m" (*&cw)) -#define _FPU_SETCW(cw) __asm__ ("ld %0,%%fsr" : : "m" (*&cw)) +#if __WORDSIZE == 64 +# define _FPU_GETCW(cw) __asm__ __volatile__ ("stx %%fsr,%0" : "=m" (*&cw)) +# define _FPU_SETCW(cw) __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (*&cw)) +#else +# ifdef __leon__ + /* Prevent stfsr from being placed directly after other fp instruction. */ +# define _FPU_GETCW(cw) __asm__ __volatile__ ("nop; st %%fsr,%0" : "=m" (*&cw)) +# else +# define _FPU_GETCW(cw) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (*&cw)) +# endif +# define _FPU_SETCW(cw) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (*&cw)) +#endif -#if 0 /* Default control word set at startup. */ extern fpu_control_t __fpu_control; -#endif #endif /* fpu_control.h */ diff --git a/libc/sysdeps/linux/sparc/sigaction.c b/libc/sysdeps/linux/sparc/sigaction.c index 7895e3acd..447943e3a 100644 --- a/libc/sysdeps/linux/sparc/sigaction.c +++ b/libc/sysdeps/linux/sparc/sigaction.c @@ -30,8 +30,8 @@ _syscall5(int, rt_sigaction, int, a, int, b, int, c, int, d, int, e) -static void __rt_sigreturn_stub(void); -static void __sigreturn_stub(void); +void __rt_sigreturn_stub(void); +void __sigreturn_stub(void); int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { @@ -75,24 +75,3 @@ libc_hidden_weak(sigaction) # endif #endif - -static void -__rt_sigreturn_stub(void) -{ - __asm__( - "mov %0, %%g1\n\t" - "ta 0x10\n\t" - : /* no outputs */ - : "i" (__NR_rt_sigreturn) - ); -} -static void -__sigreturn_stub(void) -{ - __asm__( - "mov %0, %%g1\n\t" - "ta 0x10\n\t" - : /* no outputs */ - : "i" (__NR_sigreturn) - ); -} diff --git a/libc/sysdeps/linux/sparc/sigreturn_stub.S b/libc/sysdeps/linux/sparc/sigreturn_stub.S new file mode 100644 index 000000000..33f51409b --- /dev/null +++ b/libc/sysdeps/linux/sparc/sigreturn_stub.S @@ -0,0 +1,14 @@ +#include <sysdep.h> + + nop + nop + +ENTRY_NOCFI (__rt_sigreturn_stub) + mov __NR_rt_sigreturn, %g1 + ta 0x10 +END_NOCFI (__rt_sigreturn_stub) + +ENTRY_NOCFI (__sigreturn_stub) + mov __NR_sigreturn, %g1 + ta 0x10 +END_NOCFI (__sigreturn_stub) diff --git a/libc/sysdeps/linux/sparc/sysdep.h b/libc/sysdeps/linux/sparc/sysdep.h index c3897ec08..761d21454 100644 --- a/libc/sysdeps/linux/sparc/sysdep.h +++ b/libc/sysdeps/linux/sparc/sysdep.h @@ -17,6 +17,15 @@ C_LABEL(name) \ cfi_startproc; +#define ENTRY_NOCFI(name) \ + .align 4; \ + .global C_SYMBOL_NAME(name); \ + .type name, @function; \ +C_LABEL(name) + +#define END_NOCFI(name) \ + .size name, . - name + #define END(name) \ cfi_endproc; \ .size name, . - name diff --git a/libc/sysdeps/linux/sparc64/Makefile.arch b/libc/sysdeps/linux/sparc64/Makefile.arch index 37b539b3b..cc4000b78 100644 --- a/libc/sysdeps/linux/sparc64/Makefile.arch +++ b/libc/sysdeps/linux/sparc64/Makefile.arch @@ -5,7 +5,7 @@ CSRC-y := __syscall_error.c sigaction.c SSRC-y := __longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S brk.S fork.S \ - syscall.S pipe.S vfork.S clone.S + syscall.S pipe.S vfork.S clone.S sigreturn_stub.S CSRC-y += $(addprefix soft-fp/, \ qp_add.c qp_cmp.c qp_cmpe.c qp_div.c qp_dtoq.c qp_feq.c qp_fge.c \ diff --git a/libc/sysdeps/linux/sparc64/bits/fcntl.h b/libc/sysdeps/linux/sparc64/bits/fcntl.h index 395c95baf..00e91a671 100644 --- a/libc/sysdeps/linux/sparc64/bits/fcntl.h +++ b/libc/sysdeps/linux/sparc64/bits/fcntl.h @@ -248,3 +248,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/sparc64/bits/stat.h b/libc/sysdeps/linux/sparc64/bits/stat.h index 8516b159c..62b48b745 100644 --- a/libc/sysdeps/linux/sparc64/bits/stat.h +++ b/libc/sysdeps/linux/sparc64/bits/stat.h @@ -58,7 +58,7 @@ struct stat #else __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ #endif -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -101,7 +101,7 @@ struct stat64 __blksize_t st_blksize; /* Optimal block size for I/O. */ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the diff --git a/libc/sysdeps/linux/sparc64/sigaction.c b/libc/sysdeps/linux/sparc64/sigaction.c index d8aaad0fb..b28fa659a 100644 --- a/libc/sysdeps/linux/sparc64/sigaction.c +++ b/libc/sysdeps/linux/sparc64/sigaction.c @@ -26,7 +26,7 @@ /* SPARC 64bit userland requires a kernel that has rt signals anyway. */ -static void __rt_sigreturn_stub (void); +void __rt_sigreturn_stub (void); int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) { @@ -67,11 +67,3 @@ libc_hidden_weak(sigaction) # endif #endif -static void -__rt_sigreturn_stub (void) -{ - __asm__ ("mov %0, %%g1\n\t" - "ta 0x6d\n\t" - : /* no outputs */ - : "i" (__NR_rt_sigreturn)); -} diff --git a/libc/sysdeps/linux/sparc64/sigreturn_stub.S b/libc/sysdeps/linux/sparc64/sigreturn_stub.S new file mode 100644 index 000000000..a5c9bb47f --- /dev/null +++ b/libc/sysdeps/linux/sparc64/sigreturn_stub.S @@ -0,0 +1,10 @@ +#include <sysdep.h> + + nop + nop + +ENTRY_NOCFI (__rt_sigreturn_stub) + mov __NR_rt_sigreturn, %g1 + ta 0x6d +END_NOCFI (__rt_sigreturn_stub) + diff --git a/libc/sysdeps/linux/sparc64/sysdep.h b/libc/sysdeps/linux/sparc64/sysdep.h index 31008c34b..5a4c36348 100644 --- a/libc/sysdeps/linux/sparc64/sysdep.h +++ b/libc/sysdeps/linux/sparc64/sysdep.h @@ -83,6 +83,15 @@ C_LABEL(name) \ cfi_endproc; \ .size name, . - name +#define ENTRY_NOCFI(name) \ + .align 4; \ + .global C_SYMBOL_NAME(name); \ + .type name, @function; \ +C_LABEL(name) + +#define END_NOCFI(name) \ + .size name, . - name + #define LOC(name) .L##name #undef PSEUDO diff --git a/libc/sysdeps/linux/tile/bits/fcntl.h b/libc/sysdeps/linux/tile/bits/fcntl.h index 818da5c4a..28fda899d 100644 --- a/libc/sysdeps/linux/tile/bits/fcntl.h +++ b/libc/sysdeps/linux/tile/bits/fcntl.h @@ -229,3 +229,6 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS + +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/tile/sys/ucontext.h b/libc/sysdeps/linux/tile/sys/ucontext.h index ed2c27b58..068da8c4a 100644 --- a/libc/sysdeps/linux/tile/sys/ucontext.h +++ b/libc/sysdeps/linux/tile/sys/ucontext.h @@ -82,10 +82,10 @@ typedef struct } mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { unsigned long int __ctx(uc_flags); - struct ucontext_t *uc_link; + struct ucontext *uc_link; stack_t uc_stack; mcontext_t uc_mcontext; sigset_t uc_sigmask; diff --git a/libc/sysdeps/linux/x86_64/bits/fcntl.h b/libc/sysdeps/linux/x86_64/bits/fcntl.h index 3547a2046..821b2e3cc 100644 --- a/libc/sysdeps/linux/x86_64/bits/fcntl.h +++ b/libc/sysdeps/linux/x86_64/bits/fcntl.h @@ -259,3 +259,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/x86_64/bits/stat.h b/libc/sysdeps/linux/x86_64/bits/stat.h index a7412c8f9..a8c75feaa 100644 --- a/libc/sysdeps/linux/x86_64/bits/stat.h +++ b/libc/sysdeps/linux/x86_64/bits/stat.h @@ -77,7 +77,7 @@ struct stat #else __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ #endif -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -138,7 +138,7 @@ struct stat64 #endif __blksize_t st_blksize; /* Optimal block size for I/O. */ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the diff --git a/libc/sysdeps/linux/x86_64/crt1.S b/libc/sysdeps/linux/x86_64/crt1.S index 701cbf2f6..151aeffeb 100644 --- a/libc/sysdeps/linux/x86_64/crt1.S +++ b/libc/sysdeps/linux/x86_64/crt1.S @@ -83,11 +83,7 @@ _start: #ifdef L_rcrt1 pushq %rdi /* save rdi (but should be 0...) */ pushq %rdx /* store rdx (rtld_fini) */ - xorq %rcx, %rcx /* ensure rcx is 0 */ - addq _start@GOTPCREL(%rip), %rcx /* get offset of _start from beginning of file */ - movq _start@GOTPCREL(%rip), %rax /* get run time address of _start */ - subq %rcx, %rax /* calculate run time load offset */ - movq %rax, %rdi /* load offset -> param 1 */ + lea __ehdr_start(%rip), %rdi /* "Calculate" load address... */ call reloc_static_pie /* relocate dynamic addrs */ xorq %rax, %rax /* cleanup */ popq %rdx diff --git a/libc/sysdeps/linux/xtensa/__start_context.S b/libc/sysdeps/linux/xtensa/__start_context.S index a30d7b618..e6ce93347 100644 --- a/libc/sysdeps/linux/xtensa/__start_context.S +++ b/libc/sysdeps/linux/xtensa/__start_context.S @@ -22,9 +22,10 @@ * There's no entry instruction, makecontext sets up ucontext_t as if * getcontext was called above and is about to return here. * Registers on entry to this function: - * a12: func to call + * a12: func to call (function descriptor in case of FDPIC) * a13: ucp->uc_link, next context to activate if func returns * a14: func argc + * a15: current GOT pointer (in case of FDPIC) */ .literal_position @@ -46,14 +47,17 @@ ENTRY_PREFIX(__start_context) addi a1, a1, 16 /* func arguments 6..argc - 1 are now at the top of the stack */ 1: + FDPIC_LOAD_FUNCDESC (a12, a12) callx0 a12 beqz a13, 1f mov a2, a13 movi a4, JUMPTARGET (setcontext) + FDPIC_LOAD_JUMPTARGET (a4, a15, a4) callx0 a4 1: movi a4, JUMPTARGET (_exit) movi a2, 0 + FDPIC_LOAD_JUMPTARGET (a4, a15, a4) callx0 a4 ill END(__start_context) diff --git a/libc/sysdeps/linux/xtensa/bits/elf-fdpic.h b/libc/sysdeps/linux/xtensa/bits/elf-fdpic.h new file mode 100644 index 000000000..19bb247b8 --- /dev/null +++ b/libc/sysdeps/linux/xtensa/bits/elf-fdpic.h @@ -0,0 +1,117 @@ +/* Copyright 2003, 2004 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. + +In addition to the permissions in the GNU Lesser General Public +License, the Free Software Foundation gives you unlimited +permission to link the compiled version of this file with other +programs, and to distribute those programs without any restriction +coming from the use of this file. (The GNU Lesser General Public +License restrictions do apply in other respects; for example, they +cover modification of the file, and distribution when not linked +into another program.) + +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 +Library 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; see the file COPYING.LIB. If +not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_ELF_FDPIC_H +#define _BITS_ELF_FDPIC_H + +/* These data structures are described in the FDPIC ABI extension. + The kernel passes a process a memory map, such that for every LOAD + segment there is an elf32_fdpic_loadseg entry. A pointer to an + elf32_fdpic_loadmap is passed in r7 at start-up, and a pointer to + an additional such map is passed in r8 for the interpreter, when + there is one. */ + +#include <elf.h> + +/* This data structure represents a PT_LOAD segment. */ +struct elf32_fdpic_loadseg +{ + /* Core address to which the segment is mapped. */ + Elf32_Addr addr; + /* VMA recorded in the program header. */ + Elf32_Addr p_vaddr; + /* Size of this segment in memory. */ + Elf32_Word p_memsz; +}; + +struct elf32_fdpic_loadmap { + /* Protocol version number, must be zero. */ + Elf32_Half version; + /* Number of segments in this map. */ + Elf32_Half nsegs; + /* The actual memory map. */ + struct elf32_fdpic_loadseg segs[/*nsegs*/]; +}; + +struct elf32_fdpic_loadaddr { + struct elf32_fdpic_loadmap *map; + void *got_value; +}; + +/* Map a pointer's VMA to its corresponding address according to the + load map. */ +static __always_inline void * +__reloc_pointer (void *p, + const struct elf32_fdpic_loadmap *map) +{ + int c; + +#if 0 + if (map->version != 0) + /* Crash. */ + ((void(*)())0)(); +#endif + + /* No special provision is made for NULL. We don't want NULL + addresses to go through relocation, so they shouldn't be in + .rofixup sections, and, if they're present in dynamic + relocations, they shall be mapped to the NULL address without + undergoing relocations. */ + + for (c = 0; + /* Take advantage of the fact that the loadmap is ordered by + virtual addresses. In general there will only be 2 entries, + so it's not profitable to do a binary search. */ + c < map->nsegs && p >= (void*)map->segs[c].p_vaddr; + c++) + { + /* This should be computed as part of the pointer comparison + above, but we want to use the carry in the comparison, so we + can't convert it to an integer type beforehand. */ + unsigned long offset = (char*)p - (char*)map->segs[c].p_vaddr; + /* We only check for one-past-the-end for the last segment, + assumed to be the data segment, because other cases are + ambiguous in the absence of padding between segments, and + rofixup already serves as padding between text and data. + Unfortunately, unless we special-case the last segment, we + fail to relocate the _end symbol. */ + if (offset < map->segs[c].p_memsz + || (offset == map->segs[c].p_memsz && c + 1 == map->nsegs)) + return (char*)map->segs[c].addr + offset; + } + + /* We might want to crash instead. */ + return (void*)-1; +} + +# define __RELOC_POINTER(ptr, loadaddr) \ + (__reloc_pointer ((void*)(ptr), \ + (loadaddr).map)) + +void* +__self_reloc (const struct elf32_fdpic_loadmap *map, void ***p, void ***e); + +#endif /* _BITS_ELF_FDPIC_H */ diff --git a/libc/sysdeps/linux/xtensa/bits/fcntl.h b/libc/sysdeps/linux/xtensa/bits/fcntl.h index 5af9d2124..9bc5fa893 100644 --- a/libc/sysdeps/linux/xtensa/bits/fcntl.h +++ b/libc/sysdeps/linux/xtensa/bits/fcntl.h @@ -245,3 +245,5 @@ extern ssize_t tee (int __fdin, int __fdout, size_t __len, #endif __END_DECLS +/* Include generic Linux declarations. */ +#include <bits/fcntl-linux.h> diff --git a/libc/sysdeps/linux/xtensa/bits/stat.h b/libc/sysdeps/linux/xtensa/bits/stat.h index 045a017fd..43af825ec 100644 --- a/libc/sysdeps/linux/xtensa/bits/stat.h +++ b/libc/sysdeps/linux/xtensa/bits/stat.h @@ -54,7 +54,7 @@ struct stat unsigned long __pad2; __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ #endif -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the @@ -94,7 +94,7 @@ struct stat64 unsigned long __pad2; __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ -#ifdef __USE_MISC +#if defined(__USE_MISC) || defined(__USE_XOPEN2K8) /* Nanosecond resolution timestamps are stored in a format equivalent to 'struct timespec'. This is the type used whenever possible but the Unix namespace rules do not allow the diff --git a/libc/sysdeps/linux/xtensa/bits/xtensa-config.h b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h index b99928b1e..bfcd571d2 100644 --- a/libc/sysdeps/linux/xtensa/bits/xtensa-config.h +++ b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h @@ -32,21 +32,41 @@ macros. */ #undef XCHAL_HAVE_NSA +#ifdef __XCHAL_HAVE_NSA +#define XCHAL_HAVE_NSA __XCHAL_HAVE_NSA +#else #define XCHAL_HAVE_NSA 1 +#endif #undef XCHAL_HAVE_LOOPS +#ifdef __XCHAL_HAVE_LOOPS +#define XCHAL_HAVE_LOOPS __XCHAL_HAVE_LOOPS +#else #define XCHAL_HAVE_LOOPS 1 +#endif /* Assume the maximum number of AR registers. This currently only affects the __window_spill function, and it is always safe to flush extra. */ #undef XCHAL_NUM_AREGS +#ifdef __XCHAL_NUM_AREGS +#define XCHAL_NUM_AREGS __XCHAL_NUM_AREGS +#else #define XCHAL_NUM_AREGS 64 +#endif #undef XCHAL_HAVE_S32C1I +#ifdef __XCHAL_HAVE_S32C1I +#define XCHAL_HAVE_S32C1I __XCHAL_HAVE_S32C1I +#else #define XCHAL_HAVE_S32C1I 1 +#endif #undef XCHAL_HAVE_EXCLUSIVE +#ifdef __XCHAL_HAVE_EXCLUSIVE +#define XCHAL_HAVE_EXCLUSIVE __XCHAL_HAVE_EXCLUSIVE +#else #define XCHAL_HAVE_EXCLUSIVE 0 +#endif #endif /* !XTENSA_CONFIG_H */ diff --git a/libc/sysdeps/linux/xtensa/clone.S b/libc/sysdeps/linux/xtensa/clone.S index ebfdcc1f6..a11044cd0 100644 --- a/libc/sysdeps/linux/xtensa/clone.S +++ b/libc/sysdeps/linux/xtensa/clone.S @@ -81,11 +81,17 @@ ENTRY (__clone) callx4 a2 #elif defined(__XTENSA_CALL0_ABI__) mov a2, a9 /* load up the 'arg' parameter */ +#ifdef __FDPIC__ + mov a12, a11 + l32i a11, a7, 4 + l32i a7, a7, 0 +#endif callx0 a7 /* call the user's function */ /* Call _exit. Note that any return parameter from the user's function in a2 is seen as inputs to _exit. */ movi a0, JUMPTARGET(_exit) + FDPIC_LOAD_JUMPTARGET(a0, a12, a0) callx0 a0 #else #error Unsupported Xtensa ABI diff --git a/libc/sysdeps/linux/xtensa/crt1.S b/libc/sysdeps/linux/xtensa/crt1.S index 3fa14ae58..a12f82dd6 100644 --- a/libc/sysdeps/linux/xtensa/crt1.S +++ b/libc/sysdeps/linux/xtensa/crt1.S @@ -35,6 +35,86 @@ #include <features.h> +#if defined(__FDPIC__) + +/* This is the canonical entry point, usually the first thing in the text + segment. When the entry point runs, most register values are unspecified, + except for: + + a6 Address of .dynamic section + a5 Interpreter map + a4 Executable map + + a2 Contains a function pointer to be registered with `atexit'. + This is how the dynamic linker arranges to have DT_FINI + functions called for shared libraries that have been loaded + before this code runs. + + a1 The stack (i.e., a1+16) contains the arguments and environment: + a1+0 argc + a1+4 argv[0] + ... + a1+(4*argc) NULL + a1+(4*(argc+1)) envp[0] + ... + NULL + */ + .text + .align 4 + .literal_position + .global _start + .type _start, @function +_start: +#if defined(__XTENSA_CALL0_ABI__) + + .begin no-transform + call0 1f +2: + .end no-transform + .align 4 + .literal_position +1: + movi a15, 2b + sub a15, a0, a15 + + mov a12, a4 + mov a13, a5 + mov a14, a6 + mov a2, a4 + movi a3, __ROFIXUP_LIST__ + add a3, a3, a15 + movi a4, __ROFIXUP_END__ + add a4, a4, a15 + movi a0, __self_reloc + add a0, a0, a15 + callx0 a0 + + mov a11, a2 + movi a2, main@GOTOFFFUNCDESC + add a2, a2, a11 + l32i a3, sp, 0 /* argc */ + addi a4, sp, 4 /* argv */ + /* a5 is either 0 when static or set by the RTLD to the rtld_fini */ + mov a7, a13 + /* unused stack_end argument is what used to be argc */ + movi a5, _init@GOTOFFFUNCDESC + add a5, a5, a11 + movi a6, _fini@GOTOFFFUNCDESC + add a6, a6, a11 + + movi a0, __uClibc_main@GOTOFFFUNCDESC + add a0, a0, a11 + l32i a11, a0, 4 + l32i a0, a0, 0 + callx0 a0 + ill + +#else +#error Unsupported Xtensa ABI +#endif + +#else /* defined(__FDPIC__) */ + #ifndef __UCLIBC_CTOR_DTOR__ .weak _init .weak _fini @@ -173,3 +253,4 @@ __data_start: .long 0 .weak data_start data_start = __data_start +#endif /* defined(__FDPIC__) */ diff --git a/libc/sysdeps/linux/xtensa/crti.S b/libc/sysdeps/linux/xtensa/crti.S index ba804eb45..2923ff09d 100644 --- a/libc/sysdeps/linux/xtensa/crti.S +++ b/libc/sysdeps/linux/xtensa/crti.S @@ -3,6 +3,7 @@ .section .init .align 4 .global _init + .hidden _init .type _init, @function _init: #if defined(__XTENSA_WINDOWED_ABI__) @@ -10,6 +11,10 @@ _init: #elif defined(__XTENSA_CALL0_ABI__) addi sp, sp, -16 s32i a0, sp, 0 +#ifdef __FDPIC__ + s32i a12, sp, 4 + mov a12, a11 +#endif #else #error Unsupported Xtensa ABI #endif @@ -17,6 +22,7 @@ _init: .section .fini .align 4 .global _fini + .hidden _fini .type _fini, @function _fini: #if defined(__XTENSA_WINDOWED_ABI__) @@ -24,6 +30,10 @@ _fini: #elif defined(__XTENSA_CALL0_ABI__) addi sp, sp, -16 s32i a0, sp, 0 +#ifdef __FDPIC__ + s32i a12, sp, 4 + mov a12, a11 +#endif #else #error Unsupported Xtensa ABI #endif diff --git a/libc/sysdeps/linux/xtensa/crtn.S b/libc/sysdeps/linux/xtensa/crtn.S index a3598da1a..6f797e8bd 100644 --- a/libc/sysdeps/linux/xtensa/crtn.S +++ b/libc/sysdeps/linux/xtensa/crtn.S @@ -4,6 +4,9 @@ #if defined(__XTENSA_WINDOWED_ABI__) retw #elif defined(__XTENSA_CALL0_ABI__) +#ifdef __FDPIC__ + l32i a12, sp, 4 +#endif l32i a0, sp, 0 addi sp, sp, 16 ret @@ -15,6 +18,9 @@ #if defined(__XTENSA_WINDOWED_ABI__) retw #elif defined(__XTENSA_CALL0_ABI__) +#ifdef __FDPIC__ + l32i a12, sp, 4 +#endif l32i a0, sp, 0 addi sp, sp, 16 ret diff --git a/libc/sysdeps/linux/xtensa/crtreloc.c b/libc/sysdeps/linux/xtensa/crtreloc.c new file mode 100644 index 000000000..697ef91ab --- /dev/null +++ b/libc/sysdeps/linux/xtensa/crtreloc.c @@ -0,0 +1,105 @@ +/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. + written by Alexandre Oliva <aoliva@redhat.com> +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. + +In addition to the permissions in the GNU Lesser General Public +License, the Free Software Foundation gives you unlimited +permission to link the compiled version of this file with other +programs, and to distribute those programs without any restriction +coming from the use of this file. (The GNU Lesser General Public +License restrictions do apply in other respects; for example, they +cover modification of the file, and distribution when not linked +into another program.) + +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 +Library 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; see the file COPYING.LIB. If +not, see <http://www.gnu.org/licenses/>. */ + +#ifdef __FDPIC__ + +#include <sys/types.h> +#include <link.h> + +/* This file is to be compiled into crt object files, to enable + executables to easily self-relocate. */ + +/* Compute the runtime address of pointer in the range [p,e), and then + map the pointer pointed by it. */ +static __always_inline void *** +reloc_range_indirect (void ***p, void ***e, + const struct elf32_fdpic_loadmap *map) +{ + while (p < e) + { + if (*p != (void **)-1) + { + void *ptr = __reloc_pointer (*p, map); + + if (ptr != (void *)-1) + { + unsigned long off = ((unsigned long)ptr & 3) * 8; + unsigned long *pa = (unsigned long *)((unsigned long)ptr & -4); + unsigned long v2; + void *pt; + + if (off) + { + unsigned long v0, v1; +#ifdef __XTENSA_EB__ + v0 = pa[1]; v1 = pa[0]; + v2 = (v1 >> (32 - off)) | (v0 << off); +#else /* __XTENSA_EL__ */ + v0 = pa[0]; v1 = pa[1]; + v2 = (v0 << (32 - off)) | (v1 >> off); +#endif + pt = (void *)((v1 << (32 - off)) | (v0 >> off)); + } + else + pt = *(void**)ptr; + pt = __reloc_pointer (pt, map); + if (off) + { + unsigned long v = (unsigned long)pt; +#ifdef __XTENSA_EB__ + pa[0] = (v2 << (32 - off)) | (v >> off); + pa[1] = (v << (32 - off)) | (v2 >> off); +#else /* __XTENSA_EL__ */ + pa[0] = (v2 >> (32 - off)) | (v << off); + pa[1] = (v >> (32 - off)) | (v2 << off); +#endif + } + else + *(void**)ptr = pt; + } + } + p++; + } + return p; +} + +/* Call __reloc_range_indirect for the given range except for the last + entry, whose contents are only relocated. It's expected to hold + the GOT value. */ +attribute_hidden void* +__self_reloc (const struct elf32_fdpic_loadmap *map, + void ***p, void ***e) +{ + p = reloc_range_indirect (p, e-1, map); + + if (p >= e) + return (void*)-1; + + return __reloc_pointer (*p, map); +} + +#endif /* __FDPIC__ */ diff --git a/libc/sysdeps/linux/xtensa/getcontext.S b/libc/sysdeps/linux/xtensa/getcontext.S index 7588a91b3..4cc644552 100644 --- a/libc/sysdeps/linux/xtensa/getcontext.S +++ b/libc/sysdeps/linux/xtensa/getcontext.S @@ -33,6 +33,7 @@ ENTRY(__getcontext) addi a4, a2, UCONTEXT_SIGMASK movi a2, SIG_BLOCK movi a5, JUMPTARGET (sigprocmask) + FDPIC_LOAD_JUMPTARGET (a5, a11, a5) jx a5 END(__getcontext) #elif defined(__XTENSA_WINDOWED_ABI__) diff --git a/libc/sysdeps/linux/xtensa/makecontext.c b/libc/sysdeps/linux/xtensa/makecontext.c index da26a0130..0a8f7116f 100644 --- a/libc/sysdeps/linux/xtensa/makecontext.c +++ b/libc/sysdeps/linux/xtensa/makecontext.c @@ -73,7 +73,12 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) sp -= 4 * (argc + 2); sp &= -16; +#ifdef __FDPIC__ + ucp->uc_mcontext.sc_pc = ((unsigned long *) __start_context)[0]; + ucp->uc_mcontext.sc_a[15] = ((unsigned long *) __start_context)[1]; +#else ucp->uc_mcontext.sc_pc = (unsigned long) __start_context; +#endif ucp->uc_mcontext.sc_a[1] = sp; ucp->uc_mcontext.sc_a[12] = (unsigned long) func; ucp->uc_mcontext.sc_a[13] = (unsigned long) ucp->uc_link; diff --git a/libc/sysdeps/linux/xtensa/setcontext.S b/libc/sysdeps/linux/xtensa/setcontext.S index 4df7cc049..72915ef8d 100644 --- a/libc/sysdeps/linux/xtensa/setcontext.S +++ b/libc/sysdeps/linux/xtensa/setcontext.S @@ -28,6 +28,7 @@ ENTRY(__setcontext) movi a4, 0 movi a2, SIG_SETMASK movi a5, JUMPTARGET (sigprocmask) + FDPIC_LOAD_JUMPTARGET (a5, a11, a5) callx0 a5 bnez a2, .Lerror diff --git a/libc/sysdeps/linux/xtensa/setjmp.S b/libc/sysdeps/linux/xtensa/setjmp.S index b8152fdd8..d629c11a8 100644 --- a/libc/sysdeps/linux/xtensa/setjmp.S +++ b/libc/sysdeps/linux/xtensa/setjmp.S @@ -155,7 +155,8 @@ ENTRY (__sigsetjmp) s32i a14, a2, 16 s32i a15, a2, 20 mov a12, a2 - movi a0, __sigjmp_save + movi a0, JUMPTARGET(__sigjmp_save) + FDPIC_LOAD_JUMPTARGET(a0, a11, a0) callx0 a0 l32i a0, a12, 0 l32i a12, a12, 8 diff --git a/libc/sysdeps/linux/xtensa/swapcontext.S b/libc/sysdeps/linux/xtensa/swapcontext.S index a215edc6d..40b38e98c 100644 --- a/libc/sysdeps/linux/xtensa/swapcontext.S +++ b/libc/sysdeps/linux/xtensa/swapcontext.S @@ -36,6 +36,7 @@ ENTRY(__swapcontext) addi a4, a2, UCONTEXT_SIGMASK movi a2, SIG_SETMASK movi a5, JUMPTARGET (sigprocmask) + FDPIC_LOAD_JUMPTARGET (a5, a11, a5) callx0 a5 bnez a2, .Lerror diff --git a/libc/sysdeps/linux/xtensa/sysdep.h b/libc/sysdeps/linux/xtensa/sysdep.h index 80b3f30fc..d05741027 100644 --- a/libc/sysdeps/linux/xtensa/sysdep.h +++ b/libc/sysdeps/linux/xtensa/sysdep.h @@ -75,13 +75,27 @@ #define LITERAL_POSITION .literal_position #undef JUMPTARGET -#ifdef __PIC__ +#if defined(__FDPIC__) +#define JUMPTARGET(name) name##@GOTOFFFUNCDESC +#define FDPIC_LOAD_FUNCDESC(call_target, funcdesc) \ + l32i a11, funcdesc, 4; \ + l32i call_target, funcdesc, 0 + +#define FDPIC_LOAD_JUMPTARGET(call_target, got_base, jumptarget)\ + add call_target, got_base, jumptarget; \ + FDPIC_LOAD_FUNCDESC(call_target, call_target) + +#elif defined(__PIC__) /* The "@PLT" suffix is currently a no-op for non-shared linking, but it doesn't hurt to use it conditionally for PIC code in case that changes someday. */ #define JUMPTARGET(name) name##@PLT +#define FDPIC_LOAD_FUNCDESC(call_target, funcdesc) +#define FDPIC_LOAD_JUMPTARGET(call_target, got_base, jumptarget) #else #define JUMPTARGET(name) name +#define FDPIC_LOAD_FUNCDESC(call_target, funcdesc) +#define FDPIC_LOAD_JUMPTARGET(call_target, got_base, jumptarget) #endif #ifndef FRAMESIZE @@ -153,6 +167,21 @@ #if defined _LIBC_REENTRANT # if defined USE___THREAD +#ifdef __FDPIC__ +# define SYSCALL_ERROR_ERRNO errno +# define SYSCALL_ERROR_HANDLER \ +0: rur a4, THREADPTR; \ + movi a3, SYSCALL_ERROR_ERRNO@GOTTPOFF; \ + .reloc ., R_XTENSA_TLS_TPOFF_PTR, SYSCALL_ERROR_ERRNO; \ + add a3, a3, a11; \ + .reloc ., R_XTENSA_TLS_TPOFF_LOAD, SYSCALL_ERROR_ERRNO; \ + l32i a3, a3, 0; \ + neg a2, a2; \ + add a4, a4, a3; \ + s32i a2, a4, 0; \ + movi a2, -1; \ + j .Lpseudo_end; +#else # define SYSCALL_ERROR_ERRNO errno # define SYSCALL_ERROR_HANDLER \ 0: rur a4, THREADPTR; \ @@ -162,13 +191,14 @@ s32i a2, a4, 0; \ movi a2, -1; \ j .Lpseudo_end; +#endif # else /* !USE___THREAD */ #if defined(__XTENSA_WINDOWED_ABI__) # define SYSCALL_ERROR_HANDLER \ 0: neg a2, a2; \ mov a6, a2; \ - movi a4, __errno_location@PLT; \ + movi a4, JUMPTARGET(__errno_location); \ callx4 a4; \ s32i a2, a6, 0; \ movi a2, -1; \ @@ -179,7 +209,8 @@ addi a1, a1, -16; \ s32i a0, a1, 0; \ s32i a2, a1, 4; \ - movi a0, __errno_location@PLT; \ + movi a0, JUMPTARGET(__errno_location); \ + FDPIC_LOAD_JUMPTARGET(a0, a11, a0); \ callx0 a0; \ l32i a0, a1, 0; \ l32i a3, a1, 4; \ @@ -193,12 +224,23 @@ # endif /* !USE___THREAD */ #else /* !_LIBC_REENTRANT */ +#ifdef __FDPIC__ +#define SYSCALL_ERROR_HANDLER \ +0: movi a4, errno@GOT; \ + add a4, a4, a11; \ + l32i a4, a4, 0; \ + neg a2, a2; \ + s32i a2, a4, 0; \ + movi a2, -1; \ + j .Lpseudo_end; +#else #define SYSCALL_ERROR_HANDLER \ 0: movi a4, errno; \ neg a2, a2; \ s32i a2, a4, 0; \ movi a2, -1; \ j .Lpseudo_end; +#endif /* __FDPIC__ */ #endif /* _LIBC_REENTRANT */ #endif /* __ASSEMBLER__ */ diff --git a/libiconv/iconv.c b/libiconv/iconv.c index ec01f381d..095932fd6 100644 --- a/libiconv/iconv.c +++ b/libiconv/iconv.c @@ -142,7 +142,7 @@ struct stateful_cd { static iconv_t combine_to_from(size_t t, size_t f) { - return (void *)(f<<16 | t<<1 | 1); + return (iconv_t)(f<<16 | t<<1 | 1); } static size_t extract_from(iconv_t cd) @@ -199,7 +199,7 @@ static void put_16(unsigned char *s, unsigned c, int e) static unsigned get_32(const unsigned char *s, int e) { e &= 3; - return s[e]+0U<<24 | s[e^1]<<16 | s[e^2]<<8 | s[e^3]; + return (s[e]+0U)<<24 | s[e^1]<<16 | s[e^2]<<8 | s[e^3]; } static void put_32(unsigned char *s, unsigned c, int e) @@ -242,7 +242,7 @@ static inline int utf8enc_wchar(char *outb, wchar_t c) } } -static inline int utf8seq_is_overlong(char *s, int n) +static inline int utf8seq_is_overlong(unsigned char *s, int n) { switch (n) { @@ -268,12 +268,12 @@ static inline int utf8seq_is_overlong(char *s, int n) return 0; } -static inline int utf8seq_is_surrogate(char *s, int n) +static inline int utf8seq_is_surrogate(unsigned char *s, int n) { return ((n == 3) && (*s == 0xED) && (*(s+1) >= 0xA0) && (*(s+1) <= 0xBF)); } -static inline int utf8seq_is_illegal(char *s, int n) +static inline int utf8seq_is_illegal(unsigned char *s, int n) { return ((n == 3) && (*s == 0xEF) && (*(s+1) == 0xBF) && (*(s+2) >= 0xBE) && (*(s+2) <= 0xBF)); @@ -331,7 +331,7 @@ static unsigned legacy_map(const unsigned char *map, unsigned c) { if (c < 4*map[-1]) return c; unsigned x = c - 4*map[-1]; - x = map[x*5/4]>>2*x%8 | map[x*5/4+1]<<8-2*x%8 & 1023; + x = map[x*5/4]>>(2*x%8) | (map[x*5/4+1]<<(8-2*x%8) & 1023); return x < 256 ? x : legacy_chars[x-256]; } @@ -382,7 +382,11 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri switch (type) { case UTF_8: if (c < 128) break; - l = utf8dec_wchar(&c, *in, *inb); + else { + wchar_t wc; + l = utf8dec_wchar(&wc, (unsigned char*)(*in), *inb); + c = wc; + } if (!l) l++; else if (l == (size_t)-1) goto ilseq; else if (l == (size_t)-2) goto starved; diff --git a/libiconv/include/jis0208.h b/libiconv/include/jis0208.h index de9c5f26a..12183ed3e 100644 --- a/libiconv/include/jis0208.h +++ b/libiconv/include/jis0208.h @@ -1,80 +1,80 @@ -12288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444,180, +{12288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444,180, 65344,168,65342,65507,65343,12541,12542,12445,12446,12291,20189,12293,12294, 12295,12540,8213,8208,65295,92,12316,8214,65372,8230,8229,8216,8217,8220,8221, 65288,65289,12308,12309,65339,65341,65371,65373,12296,12297,12298,12299,12300, 12301,12302,12303,12304,12305,65291,8722,177,215,247,65309,8800,65308,65310, 8806,8807,8734,8756,9794,9792,176,8242,8243,8451,65509,65284,162,163,65285, -65283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651, +65283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671},{9670,9633,9632,9651, 9650,9661,9660,8251,12306,8594,8592,8593,8595,12307,0,0,0,0,0,0,0,0,0,0,0, 8712,8715,8838,8839,8834,8835,8746,8745,0,0,0,0,0,0,0,0,8743,8744,172,8658, 8660,8704,8707,0,0,0,0,0,0,0,0,0,0,0,8736,8869,8978,8706,8711,8801,8786,8810, 8811,8730,8765,8733,8757,8747,8748,0,0,0,0,0,0,0,8491,8240,9839,9837,9834, -8224,8225,182,0,0,0,0,9711,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65296,65297,65298, +8224,8225,182,0,0,0,0,9711},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65296,65297,65298, 65299,65300,65301,65302,65303,65304,65305,0,0,0,0,0,0,0,65313,65314,65315, 65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328, 65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,0,0,0,0,0,0,65345, 65346,65347, 65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360, -65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,0,0,0,0,12353, +65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,0,0,0,0},{12353, 12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366, 12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379, 12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392, 12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405, 12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418, 12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431, -12432,12433,12434,12435,0,0,0,0,0,0,0,0,0,0,0,12449,12450,12451,12452,12453, +12432,12433,12434,12435,0,0,0,0,0,0,0,0,0,0,0},{12449,12450,12451,12452,12453, 12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466, 12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479, 12480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492, 12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505, 12506,12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518, 12519,12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531, -12532,12533,12534,0,0,0,0,0,0,0,0,913,914,915,916,917,918,919,920,921,922,923, +12532,12533,12534,0,0,0,0,0,0,0,0},{913,914,915,916,917,918,919,920,921,922,923, 924,925,926,927,928,929,931,932,933,934,935,936,937,0,0,0,0,0,0,0,0,945,946, 947,948,949,950,951,952,953, 954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1040,1041,1042,1043, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1040,1041,1042,1043, 1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057, 1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081, 1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096, -1097,1098,1099,1100,1101,1102,1103,0,0,0,0,0,0,0,0,0,0,0,0,0,9472,9474,9484, +1097,1098,1099,1100,1101,1102,1103,0,0,0,0,0,0,0,0,0,0,0,0,0},{9472,9474,9484, 9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507, 9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,20124,21782,23043,38463,21696,24859,25384,23030, +0,0,0,0,0,0,0,0,0,0,0,0,0,0},{20124,21782,23043,38463,21696,24859,25384,23030, 36898,33909,33564,31312,24746,25569,28197,26093,33894,33446,39925,26771,22311, 26017,25201,23451,22992,34427,39156,32098,32190,39822,25110,31903,34999,23433, 24245,25353,26263,26696,38343,38797,26447,20197,20234,20301,20381,20553,22258, 22839,22996,23041,23561,24799,24847,24944,26131,26885,28858,30031,30064,31227, 32173,32239,32963,33806,34915,35586,36949,36986,21307,20117,20133,22495,32946, 37057,30959,19968,22769,28322,36920,31282,33576,33419,39983,20801,21360,21693, -21729,22240,23035,24341,39154,28139,32996,34093,38498,38512,38560,38907,21515, +21729,22240,23035,24341,39154,28139,32996,34093},{38498,38512,38560,38907,21515, 21491,23431,28879,32701,36802,38632,21359,40284,31418,19985,30867,33276,28198, 22040,21764,27421,34074,39995,23013,21417,28006,29916,38287,22082,20113,36939, 38642,33615,39180,21473,21942,23344,24433,26144,26355,26628,27704,27891,27945, 29787,30408,31310,38964,33521,34907,35424,37613,28082,30123,30410,39365,24742, 35585,36234,38322,27022,21421,20870,22290,22576,22852,23476,24310,24616,25513, 25588,27839,28436,28814,28948,29017,29141,29503,32257,33398,33489,34199,36960, -37467,40219,22633,26044,27738,29989,20985,22830,22885,24448,24540,25276,26106, +37467,40219,22633,26044,27738,29989,20985,22830,22885,24448,24540},{25276,26106, 27178,27431,27572,29579,32705,35158,40236,40206,40644,23713,27798,33659,20740, 23627,25014,33222,26742,29281,20057,20474,21368,24681,28201,31311,38899,19979, 21270,20206,20309,20285,20385,20339,21152,21487,22025,22799,23233,23478,23521, @@ -82,21 +82,21 @@ 33499,33540,33655,33775,33747,34662,35506,22057,36008,36838,36942,38686,34442, 20420,23784,25105,29273,30011,33253,33469,34558,36032,38597,39187,39381,20171, 20250,35299,22238,22602,22730,24315,24555,24618,24724,24674,25040,25106,25296, -25913,39745,26214,26800,28023,28784,30028,30342,32117,33445,34809,38283,38542, +25913},{39745,26214,26800,28023,28784,30028,30342,32117,33445,34809,38283,38542, 35997,20977,21182,22806,21683,23475,23830,24936,27010,28079,30861,33995,34903, 35442,37799,39608,28012,39336,34521,22435,26623,34510,37390,21123,22151,21508, 24275,25313,25785,26684,26680,27579,29554,30906,31339,35226,35282,36203,36611, 37101,38307,38548,38761,23398,23731,27005,38989,38990,25499,31520,27179,27263, 26806,39949,28511,21106,21917,24688,25324,27963,28167,28369,33883,35088,36676, 19988,39993,21494,26907,27194,38788,26666,20828,31427,33970,37340,37772,22107, -40232,26658,33541,33841,31909,21000,33477,29926,20094, +40232,26658,33541,33841},{31909,21000,33477,29926,20094, 20355,20896,23506,21002,21208,21223,24059,21914,22570,23014,23436,23448,23515, 24178,24185,24739,24863,24931,25022,25563,25954,26577,26707,26874,27454,27475, 27735,28450,28567,28485,29872,29976,30435,30475,31487,31649,31777,32233,32566, 32752,32925,33382,33694,35251,35532,36011,36996,37969,38291,38289,38306,38501, 38867,39208,33304,20024,21547,23736,24012,29609,30284,30524,23721,32747,36107, 38593,38929,38996,39000,20225,20238,21361,21916,22120,22522,22855,23305,23492, -23696,24076,24190,24524,25582,26426,26071,26082,26399,26827,26820,27231,24112, +23696,24076,24190,24524,25582,26426,26071,26082,26399,26827,26820},{27231,24112, 27589,27671,27773,30079,31048,23395,31232,32000,24509,35215,35352,36020,36215, 36556,36637,39138,39438,39740,20096,20605,20736,22931,23452,25135,25216,25836, 27450,29344,30097,31047,32681,34811,35516,35696,25516,33738,38816,21513,21507, @@ -104,21 +104,21 @@ 20037,20167,20241,21450,21560,23470,24339,24613,25937,26429,27714,27762,27875, 28792,29699,31350,31406,31496,32026,31998,32102,26087,29275,21435,23621,24040, 25298,25312,25369,28192,34394,35377,36317,37624,28417,31142,39770,20136,20139, -20140,20379,20384,20689,20807,31478,20849,20982,21332,21281,21375,21483,21932, +20140},{20379,20384,20689,20807,31478,20849,20982,21332,21281,21375,21483,21932, 22659,23777,24375,24394,24623,24656,24685,25375,25945,27211,27841,29378,29421, 30703,33016,33029,33288,34126,37111,37857,38911,39255,39514,20208,20957,23597, 26241,26989,23616,26354,26997,29577,26704,31873,20677,21220,22343,24062,37670, 26020,27427,27453,29748,31105,31165,31563,32202,33465,33740,34943,35167,35641, 36817,37329,21535,37504,20061,20534,21477,21306,29399, 29590,30697,33510,36527,39366,39368,39378,20855,24858,34398,21936,31354,20598, -23507,36935,38533,20018,27355,37351,23633,23624,25496,31391,27795,38772,36705, +23507,36935,38533,20018,27355,37351,23633,23624},{25496,31391,27795,38772,36705, 31402,29066,38536,31874,26647,32368,26705,37740,21234,21531,34219,35347,32676, 36557,37089,21350,34952,31041,20418,20670,21009,20804,21843,22317,29674,22411, 22865,24418,24452,24693,24950,24935,25001,25522,25658,25964,26223,26690,28179, 30054,31293,31995,32076,32153,32331,32619,33550,33610,34509,35336,35427,35686, 36605,38938,40335,33464,36814,39912,21127,25119,25731,28608,38553,26689,20625, 27424,27770,28500,31348,32080,34880,35363,26376,20214,20537,20518,20581,20860, -21048,21091,21927,22287,22533,23244,24314,25010,25080,25331,25458,26908,27177, +21048,21091,21927,22287,22533,23244,24314,25010,25080,25331,25458},{26908,27177, 29309,29356,29486,30740,30831,32121,30476,32937,35211,35609,36066,36562,36963, 37749,38522,38997,39443,40568,20803,21407,21427,24187,24358,28187,28304,29572, 29694,32067,33335,35328,35578,38480,20046,20491,21476,21628,22266,22993,23396, @@ -126,21 +126,21 @@ 34382,35463,36328,37431,38599,39015,40723,20116,20114,20237,21320,21577,21566, 23087,24460,24481,24735,26791,27278,29786,30849,35486,35492,35703,37264,20062, 39881,20132,20348,20399,20505,20502,20809,20844,21151,21177,21246,21402,21475, -21521,21518,21897,22353,22434,22909,23380,23389,23439,24037,24039,24055,24184, +21521},{21518,21897,22353,22434,22909,23380,23389,23439,24037,24039,24055,24184, 24195,24218,24247,24344,24658,24908,25239,25304,25511,25915,26114,26179,26356, 26477,26657,26775,27083,27743,27946,28009,28207,28317,30002,30343,30828,31295, 31968,32005,32024,32094,32177,32789,32771,32943,32945, 33108,33167,33322,33618,34892,34913,35611,36002,36092,37066,37237,37489,30783, 37628,38308,38477,38917,39321,39640,40251,21083,21163,21495,21512,22741,25335, 28640,35946,36703,40633,20811,21051,21578,22269,31296,37239,40288,40658,29508, -28425,33136,29969,24573,24794,39592,29403,36796,27492,38915,20170,22256,22372, +28425,33136,29969,24573,24794,39592,29403,36796},{27492,38915,20170,22256,22372, 22718,23130,24680,25031,26127,26118,26681,26801,28151,30165,32058,33390,39746, 20123,20304,21449,21766,23919,24038,24046,26619,27801,29811,30722,35408,37782, 35039,22352,24231,25387,20661,20652,20877,26368,21705,22622,22971,23472,24425, 25165,25505,26685,27507,28168,28797,37319,29312,30741,30758,31085,25998,32048, 33756,35009,36617,38555,21092,22312,26448,32618,36001,20916,22338,38442,22586, 27018,32948,21682,23822,22524,30869,40442,20316,21066,21643,25662,26152,26388, -26613,31364,31574,32034,37679,26716,39853,31545,21273,20874,21047,23519,25334, +26613,31364,31574,32034,37679,26716,39853,31545,21273,20874,21047},{23519,25334, 25774,25830,26413,27578,34217,38609,30352,39894,25420,37638,39851,30399,26194, 19977,20632,21442,23665,24808,25746,25955,26719,29158,29642,29987,31639,32386, 34453,35715,36059,37240,39184,26028,26283,27531,20181,20180,20282,20351,21050, @@ -148,21 +148,21 @@ 24605,25351,25903,23388,26031,26045,26088,26525,27490,27515,27663,29509,31049, 31169,31992,32025,32043,32930,33026,33267,35222,35422,35433,35430,35468,35566, 36039,36060,38604,39164,27503,20107,20284,20365,20816,23383,23546,24904,25345, -26178,27425,28363,27835,29246,29885,30164,30913,31034,32780,32819,33258,33940, +26178},{27425,28363,27835,29246,29885,30164,30913,31034,32780,32819,33258,33940, 36766,27728,40575,24335,35672,40235,31482,36600,23437, 38635,19971,21489,22519,22833,23241,23460,24713,28287,28422,30142,36074,23455, 34048,31712,20594,26612,33437,23649,34122,32286,33294,20889,23556,25448,36198, 26012,29038,31038,32023,32773,35613,36554,36974,34503,37034,20511,21242,23610, 26451,28796,29237,37196,37320,37675,33509,23490,24369,24825,20027,21462,23432, 25163,26417,27530,29417,29664,31278,33131,36259,37202,39318,20754,21463,21610, -23551,25480,27193,32172,38656,22234,21454,21608,23447,23601,24030,20462,24833, +23551,25480,27193,32172,38656,22234,21454,21608},{23447,23601,24030,20462,24833, 25342,27954,31168,31179,32066,32333,32722,33261,33311,33936,34886,35186,35728, 36468,36655,36913,37195,37228,38598,37276,20160,20303,20805,21313,24467,25102, 26580,27713,28171,29539,32294,37325,37507,21460,22809,23487,28113,31069,32302, 31899,22654,29087,20986,34899,36848,20426,23803,26149,30636,31459,33308,39423, 20934,24490,26092,26991,27529,28147,28310,28516,30462,32020,24033,36981,37255, 38918,20966,21021,25152,26257,26329,28186,24246,32210,32626,26360,34223,34295, -35576,21161,21465,22899,24207,24464,24661,37604,38500,20663,20767,21213,21280, +35576,21161,21465,22899,24207,24464,24661,37604,38500,20663,20767},{21213,21280, 21319,21484,21736,21830,21809,22039,22888,22974,23100,23477,23558,23567,23569, 23578,24196,24202,24288,24432,25215,25220,25307,25484,25463,26119,26124,26157, 26230,26494,26786,27167,27189,27836,28040,28169,28248,28988,28966,29031,30151, @@ -170,21 +170,21 @@ 34909,35059,35359,35388,35412,35443,35937,36062,37284,37478,37758,37912,38556, 38808,19978,19976,19998,20055,20887,21104,22478,22580,22732,23330,24120,24773, 25854,26465,26454,27972,29366,30067,31331,33976,35698, -37304,37664,22065,22516,39166,25325,26893,27542,29165,32340,32887,33394,35302, +37304,37664,22065,22516,39166},{25325,26893,27542,29165,32340,32887,33394,35302, 39135,34645,36785,23611,20280,20449,20405,21767,23072,23517,23529,24515,24910, 25391,26032,26187,26862,27035,28024,28145,30003,30137,30495,31070,31206,32051, 33251,33455,34218,35242,35386,36523,36763,36914,37341,38663,20154,20161,20995, 22645,22764,23563,29978,23613,33102,35338,36805,38499,38765,31525,35535,38920, 37218,22259,21416,36887,21561,22402,24101,25512,27700,28810,30561,31883,32736, 34928,36930,37204,37648,37656,38543,29790,39620,23815,23913,25968,26530,36264, -38619,25454,26441,26905,33733,38935,38592,35070,28548,25722,23544,19990,28716, +38619,25454,26441,26905,33733,38935,38592,35070},{28548,25722,23544,19990,28716, 30045,26159,20932,21046,21218,22995,24449,24615,25104,25919,25972,26143,26228, 26866,26646,27491,28165,29298,29983,30427,31934,32854,22768,35069,35199,35488, 35475,35531,36893,37266,38738,38745,25993,31246,33030,38587,24109,24796,25114, 26021,26132,26512,30707,31309,31821,32318,33034,36012,36196,36321,36447,30889, 20999,25305,25509,25666,25240,35373,31363,31680,35500,38634,32118,33292,34633, 20185,20808,21315,21344,23459,23554,23574,24029,25126,25159,25776,26643,26676, -27849,27973,27927,26579,28508,29006,29053,26059,31359,31661,32218,32330,32680, +27849,27973,27927,26579,28508,29006,29053,26059,31359,31661,32218},{32330,32680, 33146,33307,33337,34214,35438,36046,36341,36984,36983,37549,37521,38275,39854, 21069,21892,28472,28982,20840,31109,32341,33203,31950,22092,22609,23720,25514, 26366,26365,26970,29401,30095,30094,30990,31062,31199,31895,32032,32068,34311, @@ -192,21 +192,21 @@ 23435,23652,21277,24803,24819,25436,25475,25407,25531, 25805,26089,26361,24035,27085,27133,28437,29157,20105,30185,30456,31379,31967, 32207,32156,32865,33609,33624,33900,33980,34299,35013,36208,36865,36973,37783, -38684,39442,20687,22679,24974,33235,34101,36104,36896,20419,20596,21063,21363, +38684,39442,20687,22679,24974},{33235,34101,36104,36896,20419,20596,21063,21363, 24687,25417,26463,28204,36275,36895,20439,23646,36042,26063,32154,21330,34966, 20854,25539,23384,23403,23562,25613,26449,36956,20182,22810,22826,27760,35409, 21822,22549,22949,24816,25171,26561,33333,26965,38464,39364,39464,20307,22534, 23550,32784,23729,24111,24453,24608,24907,25140,26367,27888,28382,32974,33151, 33492,34955,36024,36864,36910,38538,40667,39899,20195,21488,22823,31532,37261, 38988,40441,28381,28711,21331,21828,23429,25176,25246,25299,27810,28655,29730, -35351,37944,28609,35582,33592,20967,34552,21482,21481,20294,36948,36784,22890, +35351,37944,28609,35582,33592,20967,34552,21482},{21481,20294,36948,36784,22890, 33073,24061,31466,36799,26842,35895,29432,40008,27197,35504,20025,21336,22022, 22374,25285,25506,26086,27470,28129,28251,28845,30701,31471,31658,32187,32829, 32966,34507,35477,37723,22243,22727,24382,26029,26262,27264,27573,30007,35527, 20516,30693,22320,24347,24677,26234,27744,30196,31258,32622,33268,34584,36933, 39347,31689,30044,31481,31569,33988,36880,31209,31378,33590,23265,30528,20013, 20210,23449,24544,25277,26172,26609,27880,34411,34935,35387,37198,37619,39376, -27159,28710,29482,33511,33879,36015,19969,20806,20939,21899,23541,24086,24115, +27159,28710,29482,33511,33879,36015,19969,20806,20939,21899,23541},{24086,24115, 24193,24340,24373,24427,24500,25074,25361,26274,26397,28526,29266,30010,30522, 32884,33081,33144,34678,35519,35548,36229,36339,37530,38263,38914,40165,21189, 25431,30452,26389,27784,29645,36035,37806,38515,27941, @@ -214,21 +214,21 @@ 26584,36795,34086,32180,37716,26943,28528,22378,22775,23340,32044,29226,21514, 37347,40372,20141,20302,20572,20597,21059,35998,21576,22564,23450,24093,24213, 24237,24311,24351,24716,25269,25402,25552,26799,27712,30855,31118,31243,32224, -33351,35330,35558,36420,36883,37048,37165,37336,40718,27877,25688,25826,25973, +33351,35330,35558,36420,36883},{37048,37165,37336,40718,27877,25688,25826,25973, 28404,30340,31515,36969,37841,28346,21746,24505,25764,36685,36845,37444,20856, 22635,22825,23637,24215,28155,32399,29980,36028,36578,39003,28857,20253,27583, 28593,30000,38651,20814,21520,22581,22615,22956,23648,24466,26007,26460,28193, 30331,33759,36077,36884,37117,37709,30757,30778,21162,24230,22303,22900,24594, 20498,20826,20908,20941,20992,21776,22612,22616,22871,23445,23798,23947,24764, 25237,25645,26481,26691,26812,26847,30423,28120,28271,28059,28783,29128,24403, -30168,31095,31561,31572,31570,31958,32113,21040,33891,34153,34276,35342,35588, +30168,31095,31561,31572,31570,31958,32113,21040},{33891,34153,34276,35342,35588, 35910,36367,36867,36879,37913,38518,38957,39472,38360,20685,21205,21516,22530, 23566,24999,25758,27934,30643,31461,33012,33796,36947,37509,23776,40199,21311, 24471,24499,28060,29305,30563,31167,31716,27602,29420,35501,26627,27233,20984, 31361,26932,23626,40182,33515,23493,37193,28702,22136,23663,24775,25958,27788, 35930,36929,38931,21585,26311,37389,22856,37027,20869,20045,20970,34201,35598, 28760,25466,37707,26978,39348,32260,30071,21335,26976,36575,38627,27741,20108, -23612,24336,36841,21250,36049,32905,34425,24319,26085,20083,20837,22914,23615, +23612,24336,36841,21250,36049,32905,34425,24319,26085,20083,20837},{22914,23615, 38894,20219,22922,24525,35469,28641,31152,31074,23527, 33905,29483,29105,24180,24565,25467,25754,29123,31896,20035,24316,20043,22492, 22178,24745,28611,32013,33021,33075,33215,36786,35223,34468,24052,25226,25773, @@ -236,14 +236,14 @@ 25490,25943,26479,30403,29260,32972,32954,36649,37197,20493,22521,23186,26757, 26995,29028,29437,36023,22770,36064,38506,36889,34687,31204,30695,33833,20271, 21093,21338,25293,26575,27850,30333,31636,31893,33334,34180,36843,26333,28448, -29190,32283,33707,39361,40614,20989,31665,30834,31672,32903,31560,27368,24161, +29190,32283,33707,39361,40614},{20989,31665,30834,31672,32903,31560,27368,24161, 32908,30033,30048,20843,37474,28300,30330,37271,39658,20240,32624,25244,31567, 38309,40169,22138,22617,34532,38588,20276,21028,21322,21453,21467,24070,25644, 26001,26495,27710,27726,29256,29359,29677,30036,32321,33324,34281,36009,31684, 37318,29033,38930,39151,25405,26217,30058,30436,30928,34115,34542,21290,21329, 21542,22915,24199,24444,24754,25161,25209,25259,26000,27604,27852,30130,30382, 30865,31192,32203,32631,32933,34987,35513,36027,36991,38750,39131,27147,31800, -20633,23614,24494,26503,27608,29749,30473,32654,40763,26570,31255,21305,30091, +20633,23614,24494,26503,27608,29749,30473,32654},{40763,26570,31255,21305,30091, 39661,24422,33181,33777,32920,24380,24517,30050,31558,36924,26727,23019,23195, 32016,30334,35628,20469,24426,27161,27703,28418,29922,31080,34920,35413,35961, 24287,25551,30149,31186,33495,37672,37618,33948,34541,39981,21697,24428,25996, @@ -251,21 +251,21 @@ 20904,24067,24220,24598,25206,25975,26023,26222,28014,29238,31526,33104,33178, 33433,35676,36000,36070,36212,38428,38468,20398,25771, 27494,33310,33889,34154,37096,23553,26963,39080,33914,34135,20239,21103,24489, -24133,26381,31119,33145,35079,35206,28149,24343,25173,27832,20175,29289,39826, +24133,26381},{31119,33145,35079,35206,28149,24343,25173,27832,20175,29289,39826, 20998,21563,22132,22707,24996,25198,28954,22894,31881,31966,32027,38640,25991, 32862,19993,20341,20853,22592,24163,24179,24330,26564,20006,34109,38281,38491, 31859,38913,20731,22721,30294,30887,21029,30629,34065,31622,20559,22793,29255, 31687,32232,36794,36820,36941,20415,21193,23081,24321,38829,20445,33303,37610, 22275,25429,27497,29995,35036,36628,31298,21215,22675,24917,25098,26286,27597, 31807,33769,20515,20472,21253,21574,22577,22857,23453,23792,23791,23849,24214, -25265,25447,25918,26041,26379,27861,27873,28921,30770,32299,32990,33459,33804, +25265,25447,25918,26041,26379},{27861,27873,28921,30770,32299,32990,33459,33804, 34028,34562,35090,35370,35914,37030,37586,39165,40179,40300,20047,20129,20621, 21078,22346,22952,24125,24536,24537,25151,26292,26395,26576,26834,20882,32033, 32938,33192,35584,35980,36031,37502,38450,21536,38956,21271,20693,21340,22696, 25778,26420,29287,30566,31302,37350,21187,27809,27526,22528,24140,22868,26412, 32763,20961,30406,25705,30952,39764,40635,22475,22969,26151,26522,27598,21737, 27097,24149,33180,26517,39850,26622,40018,26717,20134,20451,21448,25273,26411, -27819,36804,20397,32365,40639,19975,24930,28288,28459,34067,21619,26410,39749, +27819,36804,20397,32365,40639,19975,24930,28288},{28459,34067,21619,26410,39749, 24051,31637,23724,23494,34588,28234,34001,31252,33032,22937,31885,27665,30496, 21209,22818,28961,29279,30683,38695,40289,26891,23167,23064,20901,21517,21629, 26126,30431,36855,37528,40180,23018,29277,28357,20813,26825,32191,32236,38754, @@ -273,26 +273,26 @@ 32178,32791,33945,20786,26408,40665,30446,26466,21247,39173,23588,25147,31870, 36016,21839,24758,32011,38272,21249,20063,20918,22812,29242,32822,37326,24357, 30690,21380,24441,32004,34220,35379,36493,38742,26611,34222,37971,24841,24840, -27833,30290,35565,36664,21807,20305,20778,21191,21451,23461,24189,24736,24962, +27833,30290},{35565,36664,21807,20305,20778,21191,21451,23461,24189,24736,24962, 25558,26377,26586,28263,28044,29494,29495,30001,31056,35029,35480,36938,37009, 37109,38596,34701,22805,20104,20313,19982,35465,36671,38928,20653,24188,22934, 23481,24248,25562,25594,25793,26332,26954,27096,27915,28342,29076,29992,31407, 32650,32768,33865,33993,35201,35617,36362,36965,38525,39178,24958,25233,27442, 27779,28020,32716,32764,28096,32645,34746,35064,26469,33713,38972,38647,27931, 32097,33853,37226,20081,21365,23888,27396,28651,34253,34349,35239,21033,21519, -23653,26446,26792,29702,29827,30178,35023,35041,37324,38626,38520,24459,29575, +23653,26446,26792,29702,29827},{30178,35023,35041,37324,38626,38520,24459,29575, 31435,33870,25504,30053,21129,27969,28316,29705,30041,30827,31890,38534,31452, 40845,20406,24942,26053,34396,20102,20142,20698,20001,20940,23534,26009,26753, 28092,29471,30274,30637,31260,31975,33391,35538,36988,37327,38517,38936,21147, 32209,20523,21400,26519,28107,29136,29747,33256,36650,38563,40023,40607,29792, 22593,28057,32047,39006,20196,20278,20363,20919,21169,23994,24604,29618,31036, 33491,37428,38583,38646,38666,40599,40802,26278,27508,21015,21155,28872,35010, -24265,24651,24976,28451,29001,31806,32244,32879,34030,36899,37676,21570,39791, +24265,24651,24976,28451,29001,31806,32244,32879},{34030,36899,37676,21570,39791, 27347,28809,36034,36335,38706,21172,23105,24266,24324,26391,27004,27028,28010, 28431,29282,29436,31725,32769,32894,34635,37070,20845, 40595,31108,32907,37682,35542,20525,21644,35441,27498,36036,33031,24785,26528, 40434,20121,20120,39952,35435,34241,34152,26880,28286,30871,33109,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{ 24332,19984,19989,20010,20017,20022,20028,20031,20034,20054,20056,20098,20101, 35947,20106,33298,24333,20110,20126,20127,20128,20130,20144,20147,20150,20174, 20173,20164,20166,20162,20183,20190,20205,20191,20215,20233,20314,20272,20315, @@ -300,14 +300,14 @@ 20374,20760,20436,20447,20430,20440,20443,20433,20442,20432,20452,20453,20506, 20520,20500,20522,20517,20485,20252,20470,20513,20521,20524,20478,20463,20497, 20486,20547,20551,26371,20565,20560,20552,20570,20566,20588,20600,20608,20634, -20613,20660,20658,20681,20682,20659,20674,20694,20702,20709,20717,20707,20718, +20613,20660,20658},{20681,20682,20659,20674,20694,20702,20709,20717,20707,20718, 20729,20725,20745,20737,20738,20758,20757,20756,20762,20769,20794,20791,20796, 20795,20799,20800,20818,20812,20820,20834,31480,20841,20842,20846,20864,20866, 22232,20876,20873,20879,20881,20883,20885,20886,20900,20902,20898,20905,20906, 20907,20915,20913,20914,20912,20917,20925,20933,20937,20955,20960,34389,20969, 20973,20976,20981,20990,20996,21003,21012,21006,21031,21034,21038,21043,21049, 21071,21060,21067,21068,21086,21076,21098,21108,21097,21107,21119,21117,21133, -21140,21138,21105,21128,21137,36776,36775, +21140,21138,21105,21128,21137,36776},{36775, 21164,21165,21180,21173,21185,21197,21207,21214,21219,21222,39149,21216,21235, 21237,21240,21241,21254,21256,30008,21261,21264,21263,21269,21274,21283,21295, 21297,21299,21304,21312,21318,21317,19991,21321,21325,20950,21342,21353,21358, @@ -315,21 +315,21 @@ 38617,21471,26364,29166,21486,21480,21485,21498,21505,21565,21568,21548,21549, 21564,21550,21558,21545,21533,21582,21647,21621,21646,21599,21617,21623,21616, 21650,21627,21632,21622,21636,21648,21638,21703,21666,21688,21669,21676,21700, -21704,21672,21675,21698,21668,21694,21692,21720,21733,21734,21775,21780,21757, +21704,21672},{21675,21698,21668,21694,21692,21720,21733,21734,21775,21780,21757, 21742,21741,21754,21730,21817,21824,21859,21836,21806,21852,21829,21846,21847, 21816,21811,21853,21913,21888,21679,21898,21919,21883,21886,21912,21918,21934, 21884,21891,21929,21895,21928,21978,21957,21983,21956,21980,21988,21972,22036, 22007,22038,22014,22013,22043,22009,22094,22096,29151,22068,22070,22066,22072, 22123,22116,22063,22124,22122,22150,22144,22154,22176,22164,22159,22181,22190, 22198,22196,22210,22204,22209,22211,22208,22216,22222,22225,22227,22231,22254, -22265,22272,22271,22276,22281,22280,22283,22285,22291,22296,22294,21959,22300, +22265,22272,22271,22276,22281},{22280,22283,22285,22291,22296,22294,21959,22300, 22310,22327,22328,22350,22331,22336,22351,22377,22464,22408,22369,22399,22409, 22419,22432,22451,22436,22442,22448,22467,22470,22484,22482,22483,22538,22486, 22499,22539,22553,22557,22642,22561,22626,22603,22640,27584,22610,22589,22649, 22661,22713,22687,22699,22714,22750,22715,22712,22702,22725,22739,22737,22743, 22745,22744,22757,22748,22756,22751,22767,22778,22777, 22779,22780,22781,22786,22794,22800,22811,26790,22821,22828,22829,22834,22840, -22846,31442,22869,22864,22862,22874,22872,22882,22880,22887,22892,22889,22904, +22846,31442,22869,22864,22862,22874,22872,22882,22880,22887,22892,22889},{22904, 22913,22941,20318,20395,22947,22962,22982,23016,23004,22925,23001,23002,23077, 23071,23057,23068,23049,23066,23104,23148,23113,23093,23094,23138,23146,23194, 23228,23230,23243,23234,23229,23267,23255,23270,23273,23254,23290,23291,23308, @@ -337,21 +337,21 @@ 23387,23397,23401,23408,23411,23413,23416,25992,23418,23424,23427,23462,23480, 23491,23495,23497,23508,23504,23524,23526,23522,23518,23525,23531,23536,23542, 23539,23557,23559,23560,23565,23571,23584,23586,23592,23608,23609,23617,23622, -23630,23635,23632,23631,23409,23660,23662,20066,23670,23673,23692,23697,23700, +23630,23635},{23632,23631,23409,23660,23662,20066,23670,23673,23692,23697,23700, 22939,23723,23739,23734,23740,23735,23749,23742,23751,23769,23785,23805,23802, 23789,23948,23786,23819,23829,23831,23900,23839,23835,23825,23828,23842,23834, 23833,23832,23884,23890,23886,23883,23916,23923,23926,23943,23940,23938,23970, 23965,23980,23982,23997,23952,23991,23996,24009,24013,24019,24018,24022,24027, 24043,24050,24053,24075,24090,24089,24081,24091,24118,24119,24132,24131,24128, 24142,24151,24148,24159,24162,24164,24135,24181,24182,24186,40636,24191,24224, -24257,24258,24264,24272,24271,24278,24291,24285,24282,24283,24290,24289,24296, +24257,24258,24264,24272,24271},{24278,24291,24285,24282,24283,24290,24289,24296, 24297,24300,24305,24307,24304,24308,24312,24318,24323,24329,24413,24412,24331, 24337,24342,24361,24365,24376,24385,24392,24396,24398,24367,24401,24406,24407, 24409,24417,24429,24435,24439,24451,24450,24447,24458, 24456,24465,24455,24478,24473,24472,24480,24488,24493,24508,24534,24571,24548, 24568,24561,24541,24755,24575,24609,24672,24601,24592,24617,24590,24625,24603, 24597,24619,24614,24591,24634,24666,24641,24682,24695,24671,24650,24646,24653, -24675,24643,24676,24642,24684,24683,24665,24705,24717,24807,24707,24730,24708, +24675,24643,24676,24642,24684,24683,24665,24705,24717,24807,24707,24730},{24708, 24731,24726,24727,24722,24743,24715,24801,24760,24800,24787,24756,24560,24765, 24774,24757,24792,24909,24853,24838,24822,24823,24832,24820,24826,24835,24865, 24827,24817,24845,24846,24903,24894,24872,24871,24906,24895,24892,24876,24884, @@ -359,21 +359,21 @@ 24927,24925,24915,24949,24985,24982,24967,25004,24980,24986,24970,24977,25003, 25006,25036,25034,25033,25079,25032,25027,25030,25018,25035,32633,25037,25062, 25059,25078,25082,25076,25087,25085,25084,25086,25088,25096,25097,25101,25100, -25108,25115,25118,25121,25130,25134,25136,25138,25139,25153,25166,25182,25187, +25108,25115},{25118,25121,25130,25134,25136,25138,25139,25153,25166,25182,25187, 25179,25184,25192,25212,25218,25225,25214,25234,25235,25238,25300,25219,25236, 25303,25297,25275,25295,25343,25286,25812,25288,25308,25292,25290,25282,25287, 25243,25289,25356,25326,25329,25383,25346,25352,25327,25333,25424,25406,25421, 25628,25423,25494,25486,25472,25515,25462,25507,25487,25481,25503,25525,25451, 25449,25534,25577,25536,25542,25571,25545,25554,25590,25540,25622,25652,25606, 25619,25638,25654,25885,25623,25640,25615,25703,25711,25718,25678,25898,25749, -25747,25765,25769,25736,25788,25818,25810,25797,25799,25787,25816,25794,25841, +25747,25765,25769,25736,25788},{25818,25810,25797,25799,25787,25816,25794,25841, 25831,33289,25824,25825,25260,25827,25839,25900,25846, 25844,25842,25850,25856,25853,25880,25884,25861,25892,25891,25899,25908,25909, 25911,25910,25912,30027,25928,25942,25941,25933,25944,25950,25949,25970,25976, 25986,25987,35722,26011,26015,26027,26039,26051,26054,26049,26052,26060,26066, 26075,26073,26080,26081,26097,26482,26122,26115,26107,26483,26165,26166,26164, 26140,26191,26180,26185,26177,26206,26205,26212,26215,26216,26207,26210,26224, -26243,26248,26254,26249,26244,26264,26269,26305,26297,26313,26302,26300,26308, +26243,26248,26254,26249,26244,26264,26269,26305,26297,26313,26302,26300},{26308, 26296,26326,26330,26336,26175,26342,26345,26352,26357,26359,26383,26390,26398, 26406,26407,38712,26414,26431,26422,26433,26424,26423,26438,26462,26464,26457, 26467,26468,26505,26480,26537,26492,26474,26508,26507,26534,26529,26501,26551, @@ -381,21 +381,21 @@ 26566,26599,27292,26654,26694,26665,26688,26701,26674,26702,26803,26667,26713, 26723,26743,26751,26783,26767,26797,26772,26781,26779,26755,27310,26809,26740, 26805,26784,26810,26895,26765,26750,26881,26826,26888,26840,26914,26918,26849, -26892,26829,26836,26855,26837,26934,26898,26884,26839,26851,26917,26873,26848, +26892,26829},{26836,26855,26837,26934,26898,26884,26839,26851,26917,26873,26848, 26863,26920,26922,26906,26915,26913,26822,27001,26999,26972,27000,26987,26964, 27006,26990,26937,26996,26941,26969,26928,26977,26974,26973,27009,26986,27058, 27054,27088,27071,27073,27091,27070,27086,23528,27082,27101,27067,27075,27047, 27182,27025,27040,27036,27029,27060,27102,27112,27138,27163,27135,27402,27129, 27122,27111,27141,27057,27166,27117,27156,27115,27146,27154,27329,27171,27155, 27204,27148,27250,27190,27256,27207,27234,27225,27238, -27208,27192,27170,27280,27277,27296,27268,27298,27299,27287,34327,27323,27331, +27208,27192,27170,27280,27277,27296,27268,27298,27299},{27287,34327,27323,27331, 27330,27320,27315,27308,27358,27345,27359,27306,27354,27370,27387,27397,34326, 27386,27410,27414,39729,27423,27448,27447,30428,27449,39150,27463,27459,27465, 27472,27481,27476,27483,27487,27489,27512,27513,27519,27520,27524,27523,27533, 27544,27541,27550,27556,27562,27563,27567,27570,27569,27571,27575,27580,27590, 27595,27603,27615,27628,27627,27635,27631,40638,27656,27667,27668,27675,27684, 27683,27742,27733,27746,27754,27778,27789,27802,27777,27803,27774,27752,27763, -27794,27792,27844,27889,27859,27837,27863,27845,27869,27822,27825,27838,27834, +27794,27792,27844,27889,27859,27837,27863,27845,27869,27822,27825,27838},{27834, 27867,27887,27865,27882,27935,34893,27958,27947,27965,27960,27929,27957,27955, 27922,27916,28003,28051,28004,27994,28025,27993,28046,28053,28644,28037,28153, 28181,28170,28085,28103,28134,28088,28102,28140,28126,28108,28136,28114,28101, @@ -403,21 +403,21 @@ 28195,28267,28203,28278,28237,28191,28227,28218,28238,28196,28415,28189,28216, 28290,28330,28312,28361,28343,28371,28349,28335,28356,28338,28372,28373,28303, 28325,28354,28319,28481,28433,28748,28396,28408,28414,28479,28402,28465,28399, -28466,28364,28478,28435,28407,28550,28538,28536,28545,28544,28527,28507,28659, +28466,28364},{28478,28435,28407,28550,28538,28536,28545,28544,28527,28507,28659, 28525,28546,28540,28504,28558,28561,28610,28518,28595,28579,28577,28580,28601, 28614,28586,28639,28629,28652,28628,28632,28657,28654,28635,28681,28683,28666, 28689,28673,28687,28670,28699,28698,28532,28701,28696,28703,28720,28734,28722, 28753,28771,28825,28818,28847,28913,28844,28856,28851, 28846,28895,28875,28893,28889,28937,28925,28956,28953,29029,29013,29064,29030, 29026,29004,29014,29036,29071,29179,29060,29077,29096,29100,29143,29113,29118, -29138,29129,29140,29134,29152,29164,29159,29173,29180,29177,29183,29197,29200, +29138,29129,29140,29134,29152,29164,29159,29173,29180},{29177,29183,29197,29200, 29211,29224,29229,29228,29232,29234,29243,29244,29247,29248,29254,29259,29272, 29300,29310,29314,29313,29319,29330,29334,29346,29351,29369,29362,29379,29382, 29380,29390,29394,29410,29408,29409,29433,29431,20495,29463,29450,29468,29462, 29469,29492,29487,29481,29477,29502,29518,29519,40664,29527,29546,29544,29552, 29560,29557,29563,29562,29640,29619,29646,29627,29632,29669,29678,29662,29858, 29701,29807,29733,29688,29746,29754,29781,29759,29791,29785,29761,29788,29801, -29808,29795,29802,29814,29822,29835,29854,29863,29898,29903,29908,29681,29920, +29808,29795,29802,29814,29822,29835,29854,29863,29898,29903,29908,29681},{29920, 29923,29927,29929,29934,29938,29936,29937,29944,29943,29956,29955,29957,29964, 29966,29965,29973,29971,29982,29990,29996,30012,30020,30029,30026,30025,30043, 30022,30042,30057,30052,30055,30059,30061,30072,30070,30086,30087,30068,30090, @@ -425,21 +425,21 @@ 30140,30129,30157,30154,30162,30169,30179,30174,30206,30207,30204,30209,30192, 30202,30194,30195,30219,30221,30217,30239,30247,30240,30241,30242,30244,30260, 30256,30267,30279,30280,30278,30300,30296,30305,30306,30312,30313,30314,30311, -30316,30320,30322,30326,30328,30332,30336,30339,30344,30347,30350,30358,30355, +30316,30320},{30322,30326,30328,30332,30336,30339,30344,30347,30350,30358,30355, 30361,30362,30384,30388,30392,30393,30394,30402,30413,30422,30418,30430,30433, 30437,30439,30442,34351,30459,30472,30471,30468,30505, 30500,30494,30501,30502,30491,30519,30520,30535,30554,30568,30571,30555,30565, 30591,30590,30585,30606,30603,30609,30624,30622,30640,30646,30649,30655,30652, 30653,30651,30663,30669,30679,30682,30684,30691,30702,30716,30732,30738,31014, 30752,31018,30789,30862,30836,30854,30844,30874,30860,30883,30901,30890,30895, -30929,30918,30923,30932,30910,30908,30917,30922,30956,30951,30938,30973,30964, +30929,30918,30923,30932,30910,30908,30917,30922,30956},{30951,30938,30973,30964, 30983,30994,30993,31001,31020,31019,31040,31072,31063,31071,31066,31061,31059, 31098,31103,31114,31133,31143,40779,31146,31150,31155,31161,31162,31177,31189, 31207,31212,31201,31203,31240,31245,31256,31257,31264,31263,31104,31281,31291, 31294,31287,31299,31319,31305,31329,31330,31337,40861,31344,31353,31357,31368, 31383,31381,31384,31382,31401,31432,31408,31414,31429,31428,31423,36995,31431, 31434,31437,31439,31445,31443,31449,31450,31453,31457,31458,31462,31469,31472, -31490,31503,31498,31494,31539,31512,31513,31518,31541,31528,31542,31568,31610, +31490,31503,31498,31494,31539,31512,31513,31518,31541,31528,31542,31568},{31610, 31492,31565,31499,31564,31557,31605,31589,31604,31591,31600,31601,31596,31598, 31645,31640,31647,31629,31644,31642,31627,31634,31631,31581,31641,31691,31681, 31692,31695,31668,31686,31709,31721,31761,31764,31718,31717,31840,31744,31751, @@ -447,21 +447,21 @@ 31820,31811,31828,31823,31808,31824,31832,31839,31844,31830,31845,31852,31861, 31875,31888,31908,31917,31906,31915,31905,31912,31923,31922,31921,31918,31929, 31933,31936,31941,31938,31960,31954,31964,31970,39739,31983,31986,31988,31990, -31994,32006,32002,32028,32021,32010,32069,32075,32046, +31994,32006},{32002,32028,32021,32010,32069,32075,32046, 32050,32063,32053,32070,32115,32086,32078,32114,32104,32110,32079,32099,32147, 32137,32091,32143,32125,32155,32186,32174,32163,32181,32199,32189,32171,32317, 32162,32175,32220,32184,32159,32176,32216,32221,32228,32222,32251,32242,32225, 32261,32266,32291,32289,32274,32305,32287,32265,32267,32290,32326,32358,32315, 32309,32313,32323,32311,32306,32314,32359,32349,32342,32350,32345,32346,32377, 32362,32361,32380,32379,32387,32213,32381,36782,32383,32392,32393,32396,32402, -32400,32403,32404,32406,32398,32411,32412,32568,32570,32581,32588,32589,32590, +32400,32403,32404,32406,32398,32411,32412,32568,32570},{32581,32588,32589,32590, 32592,32593,32597,32596,32600,32607,32608,32616,32617,32615,32632,32642,32646, 32643,32648,32647,32652,32660,32670,32669,32666,32675,32687,32690,32697,32686, 32694,32696,35697,32709,32710,32714,32725,32724,32737,32742,32745,32755,32761, 39132,32774,32772,32779,32786,32792,32793,32796,32801,32808,32831,32827,32842, 32838,32850,32856,32858,32863,32866,32872,32883,32882,32880,32886,32889,32893, 32895,32900,32902,32901,32923,32915,32922,32941,20880,32940,32987,32997,32985, -32989,32964,32986,32982,33033,33007,33009,33051,33065,33059,33071,33099,38539, +32989,32964,32986,32982,33033,33007,33009,33051,33065,33059,33071,33099},{38539, 33094,33086,33107,33105,33020,33137,33134,33125,33126,33140,33155,33160,33162, 33152,33154,33184,33173,33188,33187,33119,33171,33193,33200,33205,33214,33208, 33213,33216,33218,33210,33225,33229,33233,33241,33240,33224,33242,33247,33248, @@ -469,21 +469,21 @@ 33323,33336,33331,33344,33369,33368,33373,33370,33375,33380,33378,33384,33386, 33387,33326,33393,33399,33400,33406,33421,33426,33451, 33439,33467,33452,33505,33507,33503,33490,33524,33523,33530,33683,33539,33531, -33529,33502,33542,33500,33545,33497,33589,33588,33558,33586,33585,33600,33593, +33529,33502,33542,33500,33545,33497},{33589,33588,33558,33586,33585,33600,33593, 33616,33605,33583,33579,33559,33560,33669,33690,33706,33695,33698,33686,33571, 33678,33671,33674,33660,33717,33651,33653,33696,33673,33704,33780,33811,33771, 33742,33789,33795,33752,33803,33729,33783,33799,33760,33778,33805,33826,33824, 33725,33848,34054,33787,33901,33834,33852,34138,33924,33911,33899,33965,33902, 33922,33897,33862,33836,33903,33913,33845,33994,33890,33977,33983,33951,34009, 33997,33979,34010,34000,33985,33990,34006,33953,34081,34047,34036,34071,34072, -34092,34079,34069,34068,34044,34112,34147,34136,34120,34113,34306,34123,34133, +34092,34079,34069,34068,34044,34112,34147,34136,34120},{34113,34306,34123,34133, 34176,34212,34184,34193,34186,34216,34157,34196,34203,34282,34183,34204,34167, 34174,34192,34249,34234,34255,34233,34256,34261,34269,34277,34268,34297,34314, 34323,34315,34302,34298,34310,34338,34330,34352,34367,34381,20053,34388,34399, 34407,34417,34451,34467,34473,34474,34443,34444,34486,34479,34500,34502,34480, 34505,34851,34475,34516,34526,34537,34540,34527,34523,34543,34578,34566,34568, 34560,34563,34555,34577,34569,34573,34553,34570,34612,34623,34615,34619,34597, -34601,34586,34656,34655,34680,34636,34638,34676,34647,34664,34670,34649,34643, +34601,34586,34656,34655,34680,34636,34638,34676,34647,34664,34670,34649},{34643, 34659,34666,34821,34722,34719,34690,34735,34763,34749,34752,34768,38614,34731, 34756,34739,34759,34758,34747,34799,34802,34784,34831,34829,34814,34806,34807, 34830,34770,34833,34838,34837,34850,34849,34865,34870,34873,34855,34875,34884, @@ -491,21 +491,21 @@ 34933,34941,34997,34930,34946,34967,34962,34990,34969,34978,34957,34980,34992, 35007,34993,35011,35012,35028,35032,35033,35037,35065,35074,35068,35060,35048, 35058,35076,35084,35082,35091,35139,35102,35109,35114,35115,35137,35140,35131, -35126,35128,35148,35101,35168,35166,35174,35172,35181,35178,35183,35188,35191, +35126,35128,35148,35101,35168,35166},{35174,35172,35181,35178,35183,35188,35191, 35198,35203,35208,35210,35219,35224,35233,35241,35238,35244,35247,35250,35258, 35261,35263,35264,35290,35292,35293,35303,35316,35320,35331,35350,35344,35340, 35355,35357,35365,35382,35393,35419,35410,35398,35400,35452,35437,35436,35426, 35461,35458,35460,35496,35489,35473,35493,35494,35482,35491,35524,35533,35522, 35546,35563,35571,35559,35556,35569,35604,35552,35554,35575,35550,35547,35596, 35591,35610,35553,35606,35600,35607,35616,35635,38827,35622,35627,35646,35624, -35649,35660,35663,35662,35657,35670,35675,35674,35691,35679,35692,35695,35700, +35649,35660,35663,35662,35657,35670,35675,35674,35691},{35679,35692,35695,35700, 35709,35712,35724,35726,35730,35731,35734,35737,35738,35898,35905,35903,35912, 35916,35918,35920,35925,35938,35948,35960,35962,35970,35977,35973,35978,35981, 35982,35988,35964,35992,25117,36013,36010,36029,36018,36019,36014,36022,36040, 36033,36068,36067,36058,36093,36090,36091,36100,36101,36106,36103,36111,36109, 36112,40782,36115,36045,36116,36118,36199,36205,36209,36211,36225,36249,36290, 36286,36282,36303,36314,36310,36300,36315,36299,36330,36331,36319,36323,36348, -36360,36361,36351,36381,36382,36368,36383,36418,36405,36400,36404,36426,36423, +36360,36361,36351,36381,36382,36368,36383,36418,36405,36400,36404,36426},{36423, 36425,36428,36432,36424,36441,36452,36448,36394,36451,36437,36470,36466,36476, 36481,36487,36485,36484,36491,36490,36499,36497,36500, 36505,36522,36513,36524,36528,36550,36529,36542,36549,36552,36555,36571,36579, @@ -513,14 +513,14 @@ 36620,36646,36659,36667,36665,36677,36674,36670,36684,36681,36678,36686,36695, 36700,36706,36707,36708,36764,36767,36771,36781,36783,36791,36826,36837,36834, 36842,36847,36999,36852,36869,36857,36858,36881,36885,36897,36877,36894,36886, -36875,36903,36918,36917,36921,36856,36943,36944,36945,36946,36878,36937,36926, +36875,36903,36918,36917,36921,36856},{36943,36944,36945,36946,36878,36937,36926, 36950,36952,36958,36968,36975,36982,38568,36978,36994,36989,36993,36992,37002, 37001,37007,37032,37039,37041,37045,37090,37092,25160,37083,37122,37138,37145, 37170,37168,37194,37206,37208,37219,37221,37225,37235,37234,37259,37257,37250, 37282,37291,37295,37290,37301,37300,37306,37312,37313,37321,37323,37328,37334, 37343,37345,37339,37372,37365,37366,37406,37375,37396,37420,37397,37393,37470, 37463,37445,37449,37476,37448,37525,37439,37451,37456,37532,37526,37523,37531, -37466,37583,37561,37559,37609,37647,37626,37700,37678,37657,37666,37658,37667, +37466,37583,37561,37559,37609,37647,37626,37700,37678},{37657,37666,37658,37667, 37690,37685,37691,37724,37728,37756,37742,37718,37808,37804,37805,37780,37817, 37846,37847,37864,37861,37848,37827,37853,37840,37832,37860,37914,37908,37907, 37891,37895,37904,37942,37931,37941,37921,37946,37953,37970,37956,37979,37984, @@ -528,21 +528,21 @@ 38274,38279,38282,38292,38294,38296,38297,38304,38312,38311,38317,38332,38331, 38329,38334,38346,28662,38339,38349,38348,38357,38356,38358,38364,38369,38373, 38370,38433,38440,38446,38447,38466,38476,38479,38475, -38519,38492,38494,38493,38495,38502,38514,38508,38541,38552,38549,38551,38570, +38519,38492,38494},{38493,38495,38502,38514,38508,38541,38552,38549,38551,38570, 38567,38577,38578,38576,38580,38582,38584,38585,38606,38603,38601,38605,35149, 38620,38669,38613,38649,38660,38662,38664,38675,38670,38673,38671,38678,38681, 38692,38698,38704,38713,38717,38718,38724,38726,38728,38722,38729,38748,38752, 38756,38758,38760,21202,38763,38769,38777,38789,38780,38785,38778,38790,38795, 38799,38800,38812,38824,38822,38819,38835,38836,38851,38854,38856,38859,38876, 38893,40783,38898,31455,38902,38901,38927,38924,38968,38948,38945,38967,38973, -38982,38991,38987,39019,39023,39024,39025,39028,39027,39082,39087,39089,39094, +38982,38991,38987,39019,39023,39024},{39025,39028,39027,39082,39087,39089,39094, 39108,39107,39110,39145,39147,39171,39177,39186,39188,39192,39201,39197,39198, 39204,39200,39212,39214,39229,39230,39234,39241,39237,39248,39243,39249,39250, 39244,39253,39319,39320,39333,39341,39342,39356,39391,39387,39389,39384,39377, 39405,39406,39409,39410,39419,39416,39425,39439,39429,39394,39449,39467,39479, 39493,39490,39488,39491,39486,39509,39501,39515,39511,39519,39522,39525,39524, 39529,39531,39530,39597,39600,39612,39616,39631,39633,39635,39636,39646,39647, -39650,39651,39654,39663,39659,39662,39668,39665,39671,39675,39686,39704,39706, +39650,39651,39654,39663,39659,39662,39668,39665,39671},{39675,39686,39704,39706, 39711,39714,39715,39717,39719,39720,39721,39722,39726,39727,39730,39748,39747, 39759,39757,39758,39761,39768,39796,39827,39811,39825,39830,39831,39839,39840, 39848,39860,39872,39882,39865,39878,39887,39889,39890,39907,39906,39908,39892, @@ -550,14 +550,14 @@ 39946,39940,39982,39963,39973,39972,39969,39984,40007, 39986,40006,39998,40026,40032,40039,40054,40056,40167,40172,40176,40201,40200, 40171,40195,40198,40234,40230,40367,40227,40223,40260,40213,40210,40257,40255, -40254,40262,40264,40285,40286,40292,40273,40272,40281,40306,40329,40327,40363, +40254,40262,40264},{40285,40286,40292,40273,40272,40281,40306,40329,40327,40363, 40303,40314,40346,40356,40361,40370,40388,40385,40379,40376,40378,40390,40399, 40386,40409,40403,40440,40422,40429,40431,40445,40474,40475,40478,40565,40569, 40573,40577,40584,40587,40588,40594,40597,40593,40605,40613,40617,40632,40618, 40621,38753,40652,40654,40655,40656,40660,40668,40670,40669,40672,40677,40680, 40687,40692,40694,40695,40697,40699,40700,40701,40711,40712,30391,40725,40737, 40748,40766,40778,40786,40788,40803,40799,40800,40801,40806,40807,40812,40810, -40823,40818,40822,40853,40860,40864,22575,27079,36953,29796,20956,29081,0,0,0, +40823,40818,40822,40853,40860,40864},{22575,27079,36953,29796,20956,29081,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0, +0,0,0,0,0,0,0} diff --git a/libm/aarch64/Makefile.arch b/libm/aarch64/Makefile.arch new file mode 100644 index 000000000..bd38690be --- /dev/null +++ b/libm/aarch64/Makefile.arch @@ -0,0 +1,16 @@ +# Makefile for uClibc-ng +# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + +ifeq ($(UCLIBC_HAS_FENV),y) +libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c) +libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC)) +endif + +libm_ARCH_OBJS:=$(libm_ARCH_OBJ) + +ifeq ($(DOPIC),y) +libm-a-y+=$(libm_ARCH_OBJS:.o=.os) +else +libm-a-y+=$(libm_ARCH_OBJS) +endif +libm-so-y+=$(libm_ARCH_OBJS:.o=.os) diff --git a/libm/aarch64/fclrexcpt.c b/libm/aarch64/fclrexcpt.c new file mode 100644 index 000000000..3dbd9a8bb --- /dev/null +++ b/libm/aarch64/fclrexcpt.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feclearexcept (int excepts) +{ + fpu_fpsr_t fpsr; + fpu_fpsr_t fpsr_new; + + excepts &= FE_ALL_EXCEPT; + + _FPU_GETFPSR (fpsr); + fpsr_new = fpsr & ~excepts; + + if (fpsr != fpsr_new) + _FPU_SETFPSR (fpsr_new); + + return 0; +} diff --git a/libm/aarch64/fedisblxcpt.c b/libm/aarch64/fedisblxcpt.c new file mode 100644 index 000000000..a36873690 --- /dev/null +++ b/libm/aarch64/fedisblxcpt.c @@ -0,0 +1,34 @@ +/* Copyright (C) 2001-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fedisableexcept (int excepts) +{ + fpu_control_t fpcr; + fpu_control_t fpcr_new; + + _FPU_GETCW (fpcr); + excepts &= FE_ALL_EXCEPT; + fpcr_new = fpcr & ~(excepts << FE_EXCEPT_SHIFT); + + if (fpcr != fpcr_new) + _FPU_SETCW (fpcr_new); + + return (fpcr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; +} diff --git a/libm/aarch64/feenablxcpt.c b/libm/aarch64/feenablxcpt.c new file mode 100644 index 000000000..b5aa3bdc6 --- /dev/null +++ b/libm/aarch64/feenablxcpt.c @@ -0,0 +1,45 @@ +/* Copyright (C) 2001-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feenableexcept (int excepts) +{ + fpu_control_t fpcr; + fpu_control_t fpcr_new; + fpu_control_t updated_fpcr; + + _FPU_GETCW (fpcr); + excepts &= FE_ALL_EXCEPT; + fpcr_new = fpcr | (excepts << FE_EXCEPT_SHIFT); + + if (fpcr != fpcr_new) + { + _FPU_SETCW (fpcr_new); + + /* Trapping exceptions are optional in AArch64; the relevant enable + bits in FPCR are RES0 hence the absence of support can be detected + by reading back the FPCR and comparing with the required value. */ + _FPU_GETCW (updated_fpcr); + + if (fpcr_new & ~updated_fpcr) + return -1; + } + + return (fpcr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; +} diff --git a/libm/aarch64/fegetenv.c b/libm/aarch64/fegetenv.c new file mode 100644 index 000000000..a85575eb8 --- /dev/null +++ b/libm/aarch64/fegetenv.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetenv (fenv_t *envp) +{ + fpu_control_t fpcr; + fpu_fpsr_t fpsr; + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + envp->__fpcr = fpcr; + envp->__fpsr = fpsr; + return 0; +} diff --git a/libm/aarch64/fegetexcept.c b/libm/aarch64/fegetexcept.c new file mode 100644 index 000000000..a9eac299c --- /dev/null +++ b/libm/aarch64/fegetexcept.c @@ -0,0 +1,26 @@ +/* Copyright (C) 2001-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetexcept (void) +{ + fpu_control_t fpcr; + _FPU_GETCW (fpcr); + return (fpcr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; +} diff --git a/libm/aarch64/fegetmode.c b/libm/aarch64/fegetmode.c new file mode 100644 index 000000000..8393e6d05 --- /dev/null +++ b/libm/aarch64/fegetmode.c @@ -0,0 +1,26 @@ +/* Store current floating-point control modes. AArch64 version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetmode (femode_t *modep) +{ + _FPU_GETCW (*modep); + return 0; +} diff --git a/libm/aarch64/fegetround.c b/libm/aarch64/fegetround.c new file mode 100644 index 000000000..1f34c6918 --- /dev/null +++ b/libm/aarch64/fegetround.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.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_FPCR_RM_MASK; +} + +int +fegetround (void) +{ + return get_rounding_mode (); +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_post.S b/libm/aarch64/feholdexcpt.c index 5e7a41926..09c8cd38b 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_post.S +++ b/libm/aarch64/feholdexcpt.c @@ -1,11 +1,9 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. +/* Copyright (C) 1997-2025 Free Software Foundation, Inc. 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. + 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 @@ -14,6 +12,14 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ -#include "../i486/sem_post.S" +#include <fenv.h> +#include "fenv_private.h" + +int +feholdexcept (fenv_t *envp) +{ + libc_feholdexcept_aarch64 (envp); + return 0; +} diff --git a/libm/aarch64/fenv_private.h b/libm/aarch64/fenv_private.h new file mode 100644 index 000000000..5afb790ea --- /dev/null +++ b/libm/aarch64/fenv_private.h @@ -0,0 +1,300 @@ +/* Private floating point rounding and exceptions handling. AArch64 version. + Copyright (C) 2014-2025 Free Software Foundation, Inc. + + 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 AARCH64_FENV_PRIVATE_H +#define AARCH64_FENV_PRIVATE_H 1 + +#include <fenv.h> +#include <fpu_control.h> + +static __always_inline void +libc_feholdexcept_aarch64 (fenv_t *envp) +{ + fpu_control_t fpcr; + fpu_control_t new_fpcr; + fpu_fpsr_t fpsr; + fpu_fpsr_t new_fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + envp->__fpcr = fpcr; + envp->__fpsr = fpsr; + + /* Clear exception flags and set all exceptions to non-stop. */ + new_fpcr = fpcr & ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT); + new_fpsr = fpsr & ~FE_ALL_EXCEPT; + + if (unlikely (new_fpcr != fpcr)) + _FPU_SETCW (new_fpcr); + + if (new_fpsr != fpsr) + _FPU_SETFPSR (new_fpsr); +} + +#define libc_feholdexcept libc_feholdexcept_aarch64 +#define libc_feholdexceptf libc_feholdexcept_aarch64 +#define libc_feholdexceptl libc_feholdexcept_aarch64 + +static __always_inline void +libc_fesetround_aarch64 (int round) +{ + fpu_control_t fpcr; + + _FPU_GETCW (fpcr); + + /* Check whether rounding modes are different. */ + round = (fpcr ^ round) & _FPU_FPCR_RM_MASK; + + /* Set new rounding mode if different. */ + if (unlikely (round != 0)) + _FPU_SETCW (fpcr ^ round); +} + +#define libc_fesetround libc_fesetround_aarch64 +#define libc_fesetroundf libc_fesetround_aarch64 +#define libc_fesetroundl libc_fesetround_aarch64 + +static __always_inline void +libc_feholdexcept_setround_aarch64 (fenv_t *envp, int round) +{ + fpu_control_t fpcr; + fpu_control_t new_fpcr; + fpu_fpsr_t fpsr; + fpu_fpsr_t new_fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + envp->__fpcr = fpcr; + envp->__fpsr = fpsr; + + /* Clear exception flags, set all exceptions to non-stop, + and set new rounding mode. */ + new_fpcr = fpcr & ~((FE_ALL_EXCEPT << FE_EXCEPT_SHIFT) | _FPU_FPCR_RM_MASK); + new_fpcr |= round; + new_fpsr = fpsr & ~FE_ALL_EXCEPT; + + if (unlikely (new_fpcr != fpcr)) + _FPU_SETCW (new_fpcr); + + if (new_fpsr != fpsr) + _FPU_SETFPSR (new_fpsr); +} + +#define libc_feholdexcept_setround libc_feholdexcept_setround_aarch64 +#define libc_feholdexcept_setroundf libc_feholdexcept_setround_aarch64 +#define libc_feholdexcept_setroundl libc_feholdexcept_setround_aarch64 + +static __always_inline int +libc_fetestexcept_aarch64 (int ex) +{ + fpu_fpsr_t fpsr; + + _FPU_GETFPSR (fpsr); + return fpsr & ex & FE_ALL_EXCEPT; +} + +#define libc_fetestexcept libc_fetestexcept_aarch64 +#define libc_fetestexceptf libc_fetestexcept_aarch64 +#define libc_fetestexceptl libc_fetestexcept_aarch64 + +static __always_inline void +libc_fesetenv_aarch64 (const fenv_t *envp) +{ + fpu_control_t fpcr; + fpu_control_t new_fpcr; + + _FPU_GETCW (fpcr); + new_fpcr = envp->__fpcr; + + if (unlikely (fpcr != new_fpcr)) + _FPU_SETCW (new_fpcr); + + _FPU_SETFPSR (envp->__fpsr); +} + +#define libc_fesetenv libc_fesetenv_aarch64 +#define libc_fesetenvf libc_fesetenv_aarch64 +#define libc_fesetenvl libc_fesetenv_aarch64 +#define libc_feresetround_noex libc_fesetenv_aarch64 +#define libc_feresetround_noexf libc_fesetenv_aarch64 +#define libc_feresetround_noexl libc_fesetenv_aarch64 + +static __always_inline int +libc_feupdateenv_test_aarch64 (const fenv_t *envp, int ex) +{ + fpu_control_t fpcr; + fpu_control_t new_fpcr; + fpu_fpsr_t fpsr; + fpu_fpsr_t new_fpsr; + int excepts; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + + /* Merge current exception flags with the saved fenv. */ + excepts = fpsr & FE_ALL_EXCEPT; + new_fpcr = envp->__fpcr; + new_fpsr = envp->__fpsr | excepts; + + if (unlikely (fpcr != new_fpcr)) + _FPU_SETCW (new_fpcr); + + if (fpsr != new_fpsr) + _FPU_SETFPSR (new_fpsr); + + /* Raise the exceptions if enabled in the new FP state. */ + if (unlikely (excepts & (new_fpcr >> FE_EXCEPT_SHIFT))) + feraiseexcept (excepts); + + return excepts & ex; +} + +#define libc_feupdateenv_test libc_feupdateenv_test_aarch64 +#define libc_feupdateenv_testf libc_feupdateenv_test_aarch64 +#define libc_feupdateenv_testl libc_feupdateenv_test_aarch64 + +static __always_inline void +libc_feupdateenv_aarch64 (const fenv_t *envp) +{ + libc_feupdateenv_test_aarch64 (envp, 0); +} + +#define libc_feupdateenv libc_feupdateenv_aarch64 +#define libc_feupdateenvf libc_feupdateenv_aarch64 +#define libc_feupdateenvl libc_feupdateenv_aarch64 + +static __always_inline void +libc_feholdsetround_aarch64 (fenv_t *envp, int round) +{ + fpu_control_t fpcr; + fpu_fpsr_t fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + envp->__fpcr = fpcr; + envp->__fpsr = fpsr; + + /* Check whether rounding modes are different. */ + round = (fpcr ^ round) & _FPU_FPCR_RM_MASK; + + /* Set new rounding mode if different. */ + if (unlikely (round != 0)) + _FPU_SETCW (fpcr ^ round); +} + +#define libc_feholdsetround libc_feholdsetround_aarch64 +#define libc_feholdsetroundf libc_feholdsetround_aarch64 +#define libc_feholdsetroundl libc_feholdsetround_aarch64 + +static __always_inline void +libc_feresetround_aarch64 (fenv_t *envp) +{ + fpu_control_t fpcr; + int round; + + _FPU_GETCW (fpcr); + + /* Check whether rounding modes are different. */ + round = (envp->__fpcr ^ fpcr) & _FPU_FPCR_RM_MASK; + + /* Restore the rounding mode if it was changed. */ + if (unlikely (round != 0)) + _FPU_SETCW (fpcr ^ round); +} + +#define libc_feresetround libc_feresetround_aarch64 +#define libc_feresetroundf libc_feresetround_aarch64 +#define libc_feresetroundl libc_feresetround_aarch64 + +/* We have support for rounding mode context. */ +#define HAVE_RM_CTX 1 + +static __always_inline void +libc_feholdsetround_aarch64_ctx (struct rm_ctx *ctx, int r) +{ + fpu_control_t fpcr; + int round; + + _FPU_GETCW (fpcr); + ctx->env.__fpcr = fpcr; + + /* Check whether rounding modes are different. */ + round = (fpcr ^ r) & _FPU_FPCR_RM_MASK; + ctx->updated_status = round != 0; + + /* Set the rounding mode if changed. */ + if (unlikely (round != 0)) + _FPU_SETCW (fpcr ^ round); +} + +#define libc_feholdsetround_ctx libc_feholdsetround_aarch64_ctx +#define libc_feholdsetroundf_ctx libc_feholdsetround_aarch64_ctx +#define libc_feholdsetroundl_ctx libc_feholdsetround_aarch64_ctx + +static __always_inline void +libc_feresetround_aarch64_ctx (struct rm_ctx *ctx) +{ + /* Restore the rounding mode if updated. */ + if (unlikely (ctx->updated_status)) + _FPU_SETCW (ctx->env.__fpcr); +} + +#define libc_feresetround_ctx libc_feresetround_aarch64_ctx +#define libc_feresetroundf_ctx libc_feresetround_aarch64_ctx +#define libc_feresetroundl_ctx libc_feresetround_aarch64_ctx + +static __always_inline void +libc_feholdsetround_noex_aarch64_ctx (struct rm_ctx *ctx, int r) +{ + fpu_control_t fpcr; + fpu_fpsr_t fpsr; + int round; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + ctx->env.__fpcr = fpcr; + ctx->env.__fpsr = fpsr; + + /* Check whether rounding modes are different. */ + round = (fpcr ^ r) & _FPU_FPCR_RM_MASK; + ctx->updated_status = round != 0; + + /* Set the rounding mode if changed. */ + if (unlikely (round != 0)) + _FPU_SETCW (fpcr ^ round); +} + +#define libc_feholdsetround_noex_ctx libc_feholdsetround_noex_aarch64_ctx +#define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_aarch64_ctx +#define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_aarch64_ctx + +static __always_inline void +libc_feresetround_noex_aarch64_ctx (struct rm_ctx *ctx) +{ + /* Restore the rounding mode if updated. */ + if (unlikely (ctx->updated_status)) + _FPU_SETCW (ctx->env.__fpcr); + + /* Write new FPSR to restore exception flags. */ + _FPU_SETFPSR (ctx->env.__fpsr); +} + +#define libc_feresetround_noex_ctx libc_feresetround_noex_aarch64_ctx +#define libc_feresetround_noexf_ctx libc_feresetround_noex_aarch64_ctx +#define libc_feresetround_noexl_ctx libc_feresetround_noex_aarch64_ctx + +#endif diff --git a/libm/aarch64/fesetenv.c b/libm/aarch64/fesetenv.c new file mode 100644 index 000000000..eb7a08da0 --- /dev/null +++ b/libm/aarch64/fesetenv.c @@ -0,0 +1,73 @@ +/* Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetenv (const fenv_t *envp) +{ + fpu_control_t fpcr; + fpu_control_t fpcr_new; + fpu_control_t updated_fpcr; + fpu_fpsr_t fpsr; + fpu_fpsr_t fpsr_new; + + _FPU_GETCW (fpcr); + + if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV)) + { + /* The new FPCR/FPSR are valid, so don't merge the reserved flags. */ + fpcr_new = envp->__fpcr; + + if (fpcr != fpcr_new) + _FPU_SETCW (fpcr_new); + + _FPU_SETFPSR (envp->__fpsr); + return 0; + } + + _FPU_GETFPSR (fpsr); + fpcr_new = fpcr & _FPU_RESERVED; + fpsr_new = fpsr & _FPU_FPSR_RESERVED; + + if (envp == FE_DFL_ENV) + { + fpcr_new |= _FPU_DEFAULT; + fpsr_new |= _FPU_FPSR_DEFAULT; + } + else + { + fpcr_new |= _FPU_FPCR_IEEE; + fpsr_new |= _FPU_FPSR_IEEE; + } + + _FPU_SETFPSR (fpsr_new); + + if (fpcr != fpcr_new) + { + _FPU_SETCW (fpcr_new); + + /* Trapping exceptions are optional in AArch64; the relevant enable + bits in FPCR are RES0 hence the absence of support can be detected + by reading back the FPCR and comparing with the required value. */ + _FPU_GETCW (updated_fpcr); + + return fpcr_new & ~updated_fpcr; + } + + return 0; +} diff --git a/libm/aarch64/fesetexcept.c b/libm/aarch64/fesetexcept.c new file mode 100644 index 000000000..14a0b4232 --- /dev/null +++ b/libm/aarch64/fesetexcept.c @@ -0,0 +1,33 @@ +/* Set given exception flags. AArch64 version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetexcept (int excepts) +{ + fpu_fpsr_t fpsr; + fpu_fpsr_t fpsr_new; + + _FPU_GETFPSR (fpsr); + fpsr_new = fpsr | (excepts & FE_ALL_EXCEPT); + if (fpsr != fpsr_new) + _FPU_SETFPSR (fpsr_new); + + return 0; +} diff --git a/libm/aarch64/fesetmode.c b/libm/aarch64/fesetmode.c new file mode 100644 index 000000000..34e7c9316 --- /dev/null +++ b/libm/aarch64/fesetmode.c @@ -0,0 +1,33 @@ +/* Install given floating-point control modes. AArch64 version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetmode (const femode_t *modep) +{ + fpu_control_t fpcr, fpcr_new; + _FPU_GETCW (fpcr); + if (modep == FE_DFL_MODE) + fpcr_new = (fpcr & _FPU_RESERVED) | _FPU_DEFAULT; + else + fpcr_new = *modep; + if (fpcr != fpcr_new) + _FPU_SETCW (fpcr_new); + return 0; +} diff --git a/libm/aarch64/fesetround.c b/libm/aarch64/fesetround.c new file mode 100644 index 000000000..63a558258 --- /dev/null +++ b/libm/aarch64/fesetround.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" +#include <fpu_control.h> + +int +fesetround (int round) +{ + if (round & ~_FPU_FPCR_RM_MASK) + return 1; + + libc_fesetround_aarch64 (round); + return 0; +} diff --git a/libm/aarch64/feupdateenv.c b/libm/aarch64/feupdateenv.c new file mode 100644 index 000000000..2b4e62ecc --- /dev/null +++ b/libm/aarch64/feupdateenv.c @@ -0,0 +1,84 @@ +/* Copyright (C) 2009-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feupdateenv (const fenv_t *envp) +{ + fpu_control_t fpcr; + fpu_control_t fpcr_new; + fpu_control_t updated_fpcr; + fpu_fpsr_t fpsr; + fpu_fpsr_t fpsr_new; + int excepts; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + excepts = fpsr & FE_ALL_EXCEPT; + + if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV)) + { + fpcr_new = envp->__fpcr; + fpsr_new = envp->__fpsr | excepts; + + if (fpcr != fpcr_new) + _FPU_SETCW (fpcr_new); + + if (fpsr != fpsr_new) + _FPU_SETFPSR (fpsr_new); + + if (excepts & (fpcr_new >> FE_EXCEPT_SHIFT)) + return feraiseexcept (excepts); + + return 0; + } + + fpcr_new = fpcr & _FPU_RESERVED; + fpsr_new = fpsr & (_FPU_FPSR_RESERVED | FE_ALL_EXCEPT); + + if (envp == FE_DFL_ENV) + { + fpcr_new |= _FPU_DEFAULT; + fpsr_new |= _FPU_FPSR_DEFAULT; + } + else + { + fpcr_new |= _FPU_FPCR_IEEE; + fpsr_new |= _FPU_FPSR_IEEE; + } + + _FPU_SETFPSR (fpsr_new); + + if (fpcr != fpcr_new) + { + _FPU_SETCW (fpcr_new); + + /* Trapping exceptions are optional in AArch64; the relevant enable + bits in FPCR are RES0 hence the absence of support can be detected + by reading back the FPCR and comparing with the required value. */ + _FPU_GETCW (updated_fpcr); + + if (fpcr_new & ~updated_fpcr) + return 1; + } + + if (excepts & (fpcr_new >> FE_EXCEPT_SHIFT)) + return feraiseexcept (excepts); + + return 0; +} diff --git a/libm/aarch64/fgetexcptflg.c b/libm/aarch64/fgetexcptflg.c new file mode 100644 index 000000000..2c8920989 --- /dev/null +++ b/libm/aarch64/fgetexcptflg.c @@ -0,0 +1,25 @@ +/* Copyright (C) 2001-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + *flagp = libc_fetestexcept_aarch64 (excepts); + return 0; +} diff --git a/libm/aarch64/fraiseexcpt.c b/libm/aarch64/fraiseexcpt.c new file mode 100644 index 000000000..6a016d046 --- /dev/null +++ b/libm/aarch64/fraiseexcpt.c @@ -0,0 +1,89 @@ +/* Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include <float.h> +#include <stdint.h> + +int +feraiseexcept (int excepts) +{ + uint64_t fpsr; + const float fp_zero = 0.0; + const float fp_one = 1.0; + const float fp_max = FLT_MAX; + const float fp_min = FLT_MIN; + const float fp_1e32 = 1.0e32f; + const float fp_two = 2.0; + const float fp_three = 3.0; + + /* Raise exceptions represented by EXCEPTS. But we must raise only + one signal at a time. It is important that if the OVERFLOW or + UNDERFLOW exception and the inexact exception are given at the + same time, the OVERFLOW or UNDERFLOW exception precedes the + INEXACT exception. + + After each exception we read from the FPSR, to force the + exception to be raised immediately. */ + + if (FE_INVALID & excepts) + __asm__ __volatile__ ( + "ldr s0, %1\n\t" + "fdiv s0, s0, s0\n\t" + "mrs %0, fpsr" : "=r" (fpsr) + : "m" (fp_zero) + : "d0"); + + if (FE_DIVBYZERO & excepts) + __asm__ __volatile__ ( + "ldr s0, %1\n\t" + "ldr s1, %2\n\t" + "fdiv s0, s0, s1\n\t" + "mrs %0, fpsr" : "=r" (fpsr) + : "m" (fp_one), "m" (fp_zero) + : "d0", "d1"); + + if (FE_OVERFLOW & excepts) + /* There's no way to raise overflow without also raising inexact. */ + __asm__ __volatile__ ( + "ldr s0, %1\n\t" + "ldr s1, %2\n\t" + "fadd s0, s0, s1\n\t" + "mrs %0, fpsr" : "=r" (fpsr) + : "m" (fp_max), "m" (fp_1e32) + : "d0", "d1"); + + if (FE_UNDERFLOW & excepts) + __asm__ __volatile__ ( + "ldr s0, %1\n\t" + "ldr s1, %2\n\t" + "fdiv s0, s0, s1\n\t" + "mrs %0, fpsr" : "=r" (fpsr) + : "m" (fp_min), "m" (fp_three) + : "d0", "d1"); + + if (FE_INEXACT & excepts) + __asm__ __volatile__ ( + "ldr s0, %1\n\t" + "ldr s1, %2\n\t" + "fdiv s0, s0, s1\n\t" + "mrs %0, fpsr" : "=r" (fpsr) + : "m" (fp_two), "m" (fp_three) + : "d0", "d1"); + + return 0; +} diff --git a/libm/aarch64/fsetexcptflg.c b/libm/aarch64/fsetexcptflg.c new file mode 100644 index 000000000..a78623d14 --- /dev/null +++ b/libm/aarch64/fsetexcptflg.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fpu_fpsr_t fpsr; + fpu_fpsr_t fpsr_new; + + /* Get the current environment. */ + _FPU_GETFPSR (fpsr); + excepts &= FE_ALL_EXCEPT; + + /* Set the desired exception mask. */ + fpsr_new = fpsr & ~excepts; + fpsr_new |= *flagp & excepts; + + /* Save state back to the FPU. */ + if (fpsr != fpsr_new) + _FPU_SETFPSR (fpsr_new); + + return 0; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S b/libm/aarch64/ftestexcept.c index 6f130d3d0..eecb93406 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S +++ b/libm/aarch64/ftestexcept.c @@ -1,11 +1,9 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. +/* Copyright (C) 1997-2025 Free Software Foundation, Inc. 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. + 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 @@ -14,6 +12,13 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ -#include "../i486/sem_wait.S" +#include <fenv.h> +#include "fenv_private.h" + +int +fetestexcept (int excepts) +{ + return libc_fetestexcept_aarch64 (excepts); +} diff --git a/libm/arc/Makefile.arch b/libm/arc/Makefile.arch new file mode 100644 index 000000000..bd38690be --- /dev/null +++ b/libm/arc/Makefile.arch @@ -0,0 +1,16 @@ +# Makefile for uClibc-ng +# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + +ifeq ($(UCLIBC_HAS_FENV),y) +libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c) +libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC)) +endif + +libm_ARCH_OBJS:=$(libm_ARCH_OBJ) + +ifeq ($(DOPIC),y) +libm-a-y+=$(libm_ARCH_OBJS:.o=.os) +else +libm-a-y+=$(libm_ARCH_OBJS) +endif +libm-so-y+=$(libm_ARCH_OBJS:.o=.os) diff --git a/libm/arc/fclrexcpt.c b/libm/arc/fclrexcpt.c new file mode 100644 index 000000000..76631657d --- /dev/null +++ b/libm/arc/fclrexcpt.c @@ -0,0 +1,34 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feclearexcept (int excepts) +{ + unsigned int fpsr; + + _FPU_GETS (fpsr); + + /* Clear the relevant bits, FWE is preserved. */ + fpsr &= ~excepts; + + _FPU_SETS (fpsr); + + return 0; +} diff --git a/libm/arc/fegetenv.c b/libm/arc/fegetenv.c new file mode 100644 index 000000000..ad332c3e5 --- /dev/null +++ b/libm/arc/fegetenv.c @@ -0,0 +1,33 @@ +/* Store current floating-point environment. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetenv (fenv_t *envp) +{ + unsigned int fpcr; + unsigned int fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETS (fpsr); + envp->__fpcr = fpcr; + envp->__fpsr = fpsr; + + return 0; +} diff --git a/libm/arc/fegetmode.c b/libm/arc/fegetmode.c new file mode 100644 index 000000000..e6aebbc87 --- /dev/null +++ b/libm/arc/fegetmode.c @@ -0,0 +1,30 @@ +/* Store current floating-point control modes. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetmode (femode_t *modep) +{ + unsigned int fpcr; + + _FPU_GETCW (fpcr); + *modep = fpcr; + + return 0; +} diff --git a/libm/arc/fegetround.c b/libm/arc/fegetround.c new file mode 100644 index 000000000..4dc476a7c --- /dev/null +++ b/libm/arc/fegetround.c @@ -0,0 +1,28 @@ +/* Return current rounding direction. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fegetround (void) +{ + unsigned int fpcr; + _FPU_GETCW (fpcr); + + return (fpcr >> __FPU_RND_SHIFT) & __FPU_RND_MASK; +} diff --git a/libm/arc/feholdexcpt.c b/libm/arc/feholdexcpt.c new file mode 100644 index 000000000..8febc7508 --- /dev/null +++ b/libm/arc/feholdexcpt.c @@ -0,0 +1,39 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +feholdexcept (fenv_t *envp) +{ + unsigned int fpcr; + unsigned int fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETS (fpsr); + + envp->__fpcr = fpcr; + envp->__fpsr = fpsr; + + fpsr &= ~FE_ALL_EXCEPT; + + _FPU_SETCW (fpcr); + _FPU_SETS (fpsr); + + return 0; +} diff --git a/libm/arc/fenv_private.h b/libm/arc/fenv_private.h new file mode 100644 index 000000000..5f74c5e13 --- /dev/null +++ b/libm/arc/fenv_private.h @@ -0,0 +1,326 @@ +/* Optimized inline fenv.h functions for libm. Generic version. + Copyright (C) 2011-2025 Free Software Foundation, Inc. + + 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_PRIVATE_H +#define _FENV_PRIVATE_H 1 + +#include <fenv.h> +#include "get-rounding-mode.h" + +/* The standards only specify one variant of the fenv.h interfaces. + But at least for some architectures we can be more efficient if we + know what operations are going to be performed. Therefore we + define additional interfaces. By default they refer to the normal + interfaces. */ + +static __always_inline void +default_libc_feholdexcept (fenv_t *e) +{ + (void) feholdexcept (e); +} + +#ifndef libc_feholdexcept +# define libc_feholdexcept default_libc_feholdexcept +#endif +#ifndef libc_feholdexceptf +# define libc_feholdexceptf default_libc_feholdexcept +#endif +#ifndef libc_feholdexceptl +# define libc_feholdexceptl default_libc_feholdexcept +#endif + +static __always_inline void +default_libc_fesetround (int r) +{ + (void) fesetround (r); +} + +#ifndef libc_fesetround +# define libc_fesetround default_libc_fesetround +#endif +#ifndef libc_fesetroundf +# define libc_fesetroundf default_libc_fesetround +#endif +#ifndef libc_fesetroundl +# define libc_fesetroundl default_libc_fesetround +#endif + +static __always_inline void +default_libc_feholdexcept_setround (fenv_t *e, int r) +{ + feholdexcept (e); + fesetround (r); +} + +#ifndef libc_feholdexcept_setround +# define libc_feholdexcept_setround default_libc_feholdexcept_setround +#endif +#ifndef libc_feholdexcept_setroundf +# define libc_feholdexcept_setroundf default_libc_feholdexcept_setround +#endif +#ifndef libc_feholdexcept_setroundl +# define libc_feholdexcept_setroundl default_libc_feholdexcept_setround +#endif + +#ifndef libc_feholdsetround_53bit +# define libc_feholdsetround_53bit libc_feholdsetround +#endif + +#ifndef libc_fetestexcept +# define libc_fetestexcept fetestexcept +#endif +#ifndef libc_fetestexceptf +# define libc_fetestexceptf fetestexcept +#endif +#ifndef libc_fetestexceptl +# define libc_fetestexceptl fetestexcept +#endif + +static __always_inline void +default_libc_fesetenv (fenv_t *e) +{ + (void) fesetenv (e); +} + +#ifndef libc_fesetenv +# define libc_fesetenv default_libc_fesetenv +#endif +#ifndef libc_fesetenvf +# define libc_fesetenvf default_libc_fesetenv +#endif +#ifndef libc_fesetenvl +# define libc_fesetenvl default_libc_fesetenv +#endif + +static __always_inline void +default_libc_feupdateenv (fenv_t *e) +{ + (void) feupdateenv (e); +} + +#ifndef libc_feupdateenv +# define libc_feupdateenv default_libc_feupdateenv +#endif +#ifndef libc_feupdateenvf +# define libc_feupdateenvf default_libc_feupdateenv +#endif +#ifndef libc_feupdateenvl +# define libc_feupdateenvl default_libc_feupdateenv +#endif + +#ifndef libc_feresetround_53bit +# define libc_feresetround_53bit libc_feresetround +#endif + +static __always_inline int +default_libc_feupdateenv_test (fenv_t *e, int ex) +{ + int ret = fetestexcept (ex); + feupdateenv (e); + return ret; +} + +#ifndef libc_feupdateenv_test +# define libc_feupdateenv_test default_libc_feupdateenv_test +#endif +#ifndef libc_feupdateenv_testf +# define libc_feupdateenv_testf default_libc_feupdateenv_test +#endif +#ifndef libc_feupdateenv_testl +# define libc_feupdateenv_testl default_libc_feupdateenv_test +#endif + +/* Save and set the rounding mode. The use of fenv_t to store the old mode + allows a target-specific version of this function to avoid converting the + rounding mode from the fpu format. By default we have no choice but to + manipulate the entire env. */ + +#ifndef libc_feholdsetround +# define libc_feholdsetround libc_feholdexcept_setround +#endif +#ifndef libc_feholdsetroundf +# define libc_feholdsetroundf libc_feholdexcept_setroundf +#endif +#ifndef libc_feholdsetroundl +# define libc_feholdsetroundl libc_feholdexcept_setroundl +#endif + +/* ... and the reverse. */ + +#ifndef libc_feresetround +# define libc_feresetround libc_feupdateenv +#endif +#ifndef libc_feresetroundf +# define libc_feresetroundf libc_feupdateenvf +#endif +#ifndef libc_feresetroundl +# define libc_feresetroundl libc_feupdateenvl +#endif + +/* ... and a version that also discards exceptions. */ + +#ifndef libc_feresetround_noex +# define libc_feresetround_noex libc_fesetenv +#endif +#ifndef libc_feresetround_noexf +# define libc_feresetround_noexf libc_fesetenvf +#endif +#ifndef libc_feresetround_noexl +# define libc_feresetround_noexl libc_fesetenvl +#endif + +#ifndef HAVE_RM_CTX +# define HAVE_RM_CTX 0 +#endif + + +/* Default implementation using standard fenv functions. + Avoid unnecessary rounding mode changes by first checking the + current rounding mode. Note the use of unlikely is + important for performance. */ + +static __always_inline void +default_libc_feholdsetround_ctx (struct rm_ctx *ctx, int round) +{ + ctx->updated_status = false; + + /* Update rounding mode only if different. */ + if (unlikely (round != get_rounding_mode ())) + { + ctx->updated_status = true; + fegetenv (&ctx->env); + fesetround (round); + } +} + +static __always_inline void +default_libc_feresetround_ctx (struct rm_ctx *ctx) +{ + /* Restore the rounding mode if updated. */ + if (unlikely (ctx->updated_status)) + feupdateenv (&ctx->env); +} + +static __always_inline void +default_libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round) +{ + /* Save exception flags and rounding mode, and disable exception + traps. */ + feholdexcept (&ctx->env); + + /* Update rounding mode only if different. */ + if (unlikely (round != get_rounding_mode ())) + fesetround (round); +} + +static __always_inline void +default_libc_feresetround_noex_ctx (struct rm_ctx *ctx) +{ + /* Restore exception flags and rounding mode. */ + fesetenv (&ctx->env); +} + +#if HAVE_RM_CTX +/* Set/Restore Rounding Modes only when necessary. If defined, these functions + set/restore floating point state only if the state needed within the lexical + block is different from the current state. This saves a lot of time when + the floating point unit is much slower than the fixed point units. */ + +# ifndef libc_feholdsetround_noex_ctx +# define libc_feholdsetround_noex_ctx libc_feholdsetround_ctx +# endif +# ifndef libc_feholdsetround_noexf_ctx +# define libc_feholdsetround_noexf_ctx libc_feholdsetroundf_ctx +# endif +# ifndef libc_feholdsetround_noexl_ctx +# define libc_feholdsetround_noexl_ctx libc_feholdsetroundl_ctx +# endif + +# ifndef libc_feresetround_noex_ctx +# define libc_feresetround_noex_ctx libc_fesetenv_ctx +# endif +# ifndef libc_feresetround_noexf_ctx +# define libc_feresetround_noexf_ctx libc_fesetenvf_ctx +# endif +# ifndef libc_feresetround_noexl_ctx +# define libc_feresetround_noexl_ctx libc_fesetenvl_ctx +# endif + +#else + +# define libc_feholdsetround_ctx default_libc_feholdsetround_ctx +# define libc_feresetround_ctx default_libc_feresetround_ctx +# define libc_feholdsetround_noex_ctx default_libc_feholdsetround_noex_ctx +# define libc_feresetround_noex_ctx default_libc_feresetround_noex_ctx + +# define libc_feholdsetroundf_ctx libc_feholdsetround_ctx +# define libc_feholdsetroundl_ctx libc_feholdsetround_ctx +# define libc_feresetroundf_ctx libc_feresetround_ctx +# define libc_feresetroundl_ctx libc_feresetround_ctx + +# define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_ctx +# define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_ctx +# define libc_feresetround_noexf_ctx libc_feresetround_noex_ctx +# define libc_feresetround_noexl_ctx libc_feresetround_noex_ctx + +#endif + +#ifndef libc_feholdsetround_53bit_ctx +# define libc_feholdsetround_53bit_ctx libc_feholdsetround_ctx +#endif +#ifndef libc_feresetround_53bit_ctx +# define libc_feresetround_53bit_ctx libc_feresetround_ctx +#endif + +#define SET_RESTORE_ROUND_GENERIC(RM,ROUNDFUNC,CLEANUPFUNC) \ + struct rm_ctx ctx __attribute__((cleanup (CLEANUPFUNC ## _ctx))); \ + ROUNDFUNC ## _ctx (&ctx, (RM)) + +/* Set the rounding mode within a lexical block. Restore the rounding mode to + the value at the start of the block. The exception mode must be preserved. + Exceptions raised within the block must be set in the exception flags. + Non-stop mode may be enabled inside the block. */ + +#define SET_RESTORE_ROUND(RM) \ + SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround) +#define SET_RESTORE_ROUNDF(RM) \ + SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundf, libc_feresetroundf) +#define SET_RESTORE_ROUNDL(RM) \ + SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetroundl) + +/* Set the rounding mode within a lexical block. Restore the rounding mode to + the value at the start of the block. The exception mode must be preserved. + Exceptions raised within the block must be discarded, and exception flags + are restored to the value at the start of the block. + Non-stop mode must be enabled inside the block. */ + +#define SET_RESTORE_ROUND_NOEX(RM) \ + SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noex, \ + libc_feresetround_noex) +#define SET_RESTORE_ROUND_NOEXF(RM) \ + SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexf, \ + libc_feresetround_noexf) +#define SET_RESTORE_ROUND_NOEXL(RM) \ + SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexl, \ + libc_feresetround_noexl) + +/* Like SET_RESTORE_ROUND, but also set rounding precision to 53 bits. */ +#define SET_RESTORE_ROUND_53BIT(RM) \ + SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_53bit, \ + libc_feresetround_53bit) + +#endif /* fenv_private.h. */ diff --git a/libm/arc/fesetenv.c b/libm/arc/fesetenv.c new file mode 100644 index 000000000..59ec3b722 --- /dev/null +++ b/libm/arc/fesetenv.c @@ -0,0 +1,44 @@ +/* Install given floating-point environment (does not raise exceptions). + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include "fpu_control.h" + +int +fesetenv (const fenv_t *envp) +{ + unsigned int fpcr; + unsigned int fpsr; + + if (envp == FE_DFL_ENV) + { + fpcr = _FPU_DEFAULT; + fpsr = _FPU_FPSR_DEFAULT; + } + else + { + /* No need to mask out reserved bits as they are IoW. */ + fpcr = envp->__fpcr; + fpsr = envp->__fpsr; + } + + _FPU_SETCW (fpcr); + _FPU_SETS (fpsr); + + /* Success. */ + return 0; +} diff --git a/libm/arc/fesetexcept.c b/libm/arc/fesetexcept.c new file mode 100644 index 000000000..3756a2e09 --- /dev/null +++ b/libm/arc/fesetexcept.c @@ -0,0 +1,31 @@ +/* Set given exception flags. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include "fpu_control.h" + +int +fesetexcept (int excepts) +{ + unsigned int fpsr; + + _FPU_GETS (fpsr); + fpsr |= excepts; + _FPU_SETS (fpsr); + + return 0; +} diff --git a/libm/arc/fesetmode.c b/libm/arc/fesetmode.c new file mode 100644 index 000000000..1fc2bdf12 --- /dev/null +++ b/libm/arc/fesetmode.c @@ -0,0 +1,39 @@ +/* Install given floating-point control modes. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include "fpu_control.h" + +int +fesetmode (const femode_t *modep) +{ + unsigned int fpcr; + + if (modep == FE_DFL_MODE) + { + fpcr = _FPU_DEFAULT; + } + else + { + /* No need to mask out reserved bits as they are IoW. */ + fpcr = *modep; + } + + _FPU_SETCW (fpcr); + + return 0; +} diff --git a/libm/arc/fesetround.c b/libm/arc/fesetround.c new file mode 100644 index 000000000..e156e9cf5 --- /dev/null +++ b/libm/arc/fesetround.c @@ -0,0 +1,36 @@ +/* Set current rounding direction. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fesetround (int round) +{ + unsigned int fpcr; + + _FPU_GETCW (fpcr); + + if (((fpcr >> __FPU_RND_SHIFT) & __FPU_RND_MASK) != round) + { + fpcr &= ~(__FPU_RND_MASK << __FPU_RND_SHIFT); + fpcr |= (round & __FPU_RND_MASK) << __FPU_RND_SHIFT; + _FPU_SETCW (fpcr); + } + + return 0; +} diff --git a/libm/arc/feupdateenv.c b/libm/arc/feupdateenv.c new file mode 100644 index 000000000..6a59b2bfe --- /dev/null +++ b/libm/arc/feupdateenv.c @@ -0,0 +1,47 @@ +/* Install given floating-point environment and raise exceptions, + without clearing currently raised exceptions. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include "fpu_control.h" + +int +feupdateenv (const fenv_t *envp) +{ + unsigned int fpcr; + unsigned int fpsr; + + _FPU_GETS (fpsr); + + if (envp == FE_DFL_ENV) + { + fpcr = _FPU_DEFAULT; + } + else + { + fpcr = envp->__fpcr; + + /* currently raised exceptions need to be preserved. */ + fpsr |= envp->__fpsr; + } + + _FPU_SETCW (fpcr); + _FPU_SETS (fpsr); + + /* Success. */ + return 0; +} diff --git a/libm/arc/fgetexcptflg.c b/libm/arc/fgetexcptflg.c new file mode 100644 index 000000000..03f97f99f --- /dev/null +++ b/libm/arc/fgetexcptflg.c @@ -0,0 +1,30 @@ +/* Store current representation for exceptions, ARC version. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + unsigned int fpsr; + + _FPU_GETS (fpsr); + *flagp = fpsr & excepts; + + return 0; +} diff --git a/libm/arc/fraiseexcpt.c b/libm/arc/fraiseexcpt.c new file mode 100644 index 000000000..2ff5e0269 --- /dev/null +++ b/libm/arc/fraiseexcpt.c @@ -0,0 +1,35 @@ +/* Raise given exceptions. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include <float.h> +#include <math.h> + +int +feraiseexcept (int excepts) +{ + unsigned int fpsr; + + /* currently raised exceptions are not cleared. */ + _FPU_GETS (fpsr); + fpsr |= excepts; + + _FPU_SETS (fpsr); + + return 0; +} diff --git a/libm/arc/fsetexcptflg.c b/libm/arc/fsetexcptflg.c new file mode 100644 index 000000000..97ff20fff --- /dev/null +++ b/libm/arc/fsetexcptflg.c @@ -0,0 +1,37 @@ +/* Set floating-point environment exception handling, ARC version. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + unsigned int fpsr; + + _FPU_GETS (fpsr); + + /* Clear the bits first. */ + fpsr &= ~excepts; + + /* Now set those bits, copying them over from @flagp. */ + fpsr |= *flagp & excepts; + + _FPU_SETS (fpsr); + + return 0; +} diff --git a/libm/arc/ftestexcept.c b/libm/arc/ftestexcept.c new file mode 100644 index 000000000..ccc557e5e --- /dev/null +++ b/libm/arc/ftestexcept.c @@ -0,0 +1,31 @@ +/* Test exception in current environment. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "fenv_private.h" +#include <stdio.h> + +int +fetestexcept (int excepts) +{ + unsigned int fpsr; + + _FPU_GETS (fpsr); + + return fpsr & excepts; +} diff --git a/libm/arc/get-rounding-mode.h b/libm/arc/get-rounding-mode.h new file mode 100644 index 000000000..d1bf3475d --- /dev/null +++ b/libm/arc/get-rounding-mode.h @@ -0,0 +1,37 @@ +/* Determine floating-point rounding mode within libc. ARC version. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + 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 _ARC_GET_ROUNDING_MODE_H +#define _ARC_GET_ROUNDING_MODE_H 1 + +#include <fenv.h> +#include <fpu_control.h> + +static inline int +get_rounding_mode (void) +{ +#if defined(__ARC_FPU_SP__) || defined(__ARC_FPU_DP__) + unsigned int fpcr; + _FPU_GETCW (fpcr); + + return (fpcr >> __FPU_RND_SHIFT) & __FPU_RND_MASK; +#else + return FE_TONEAREST; +#endif +} + +#endif /* get-rounding-mode.h */ diff --git a/libm/arm/Makefile.arch b/libm/arm/Makefile.arch new file mode 100644 index 000000000..bd38690be --- /dev/null +++ b/libm/arm/Makefile.arch @@ -0,0 +1,16 @@ +# Makefile for uClibc-ng +# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + +ifeq ($(UCLIBC_HAS_FENV),y) +libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c) +libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC)) +endif + +libm_ARCH_OBJS:=$(libm_ARCH_OBJ) + +ifeq ($(DOPIC),y) +libm-a-y+=$(libm_ARCH_OBJS:.o=.os) +else +libm-a-y+=$(libm_ARCH_OBJS) +endif +libm-so-y+=$(libm_ARCH_OBJS:.o=.os) diff --git a/libm/arm/arm-features.h b/libm/arm/arm-features.h new file mode 100644 index 000000000..8f9fd7362 --- /dev/null +++ b/libm/arm/arm-features.h @@ -0,0 +1,58 @@ +/* Macros to test for CPU features on ARM. Generic ARM version. + Copyright (C) 2012-2025 Free Software Foundation, Inc. + + 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 _ARM_ARM_FEATURES_H +#define _ARM_ARM_FEATURES_H 1 + +/* An OS-specific arm-features.h file should define ARM_HAVE_VFP to + an appropriate expression for testing at runtime whether the VFP + hardware is present. We'll then redefine it to a constant if we + know at compile time that we can assume VFP. */ + +#ifndef __SOFTFP__ +/* The compiler is generating VFP instructions, so we're already + assuming the hardware exists. */ +# undef ARM_HAVE_VFP +# define ARM_HAVE_VFP 1 +#endif + +/* An OS-specific arm-features.h file may define ARM_ASSUME_NO_IWMMXT + to indicate at compile time that iWMMXt hardware is never present + at runtime (or that we never care about its state) and so need not + be checked for. */ + +/* A more-specific arm-features.h file may define ARM_ALWAYS_BX to indicate + that instructions using pc as a destination register must never be used, + so a "bx" (or "blx") instruction is always required. */ + +/* The log2 of the minimum alignment required for an address that + is the target of a computed branch (i.e. a "bx" instruction). + A more-specific arm-features.h file may define this to set a more + stringent requirement. + + Using this only makes sense for code in ARM mode (where instructions + always have a fixed size of four bytes), or for Thumb-mode code that is + specifically aligning all the related branch targets to match (since + Thumb instructions might be either two or four bytes). */ +#ifndef ARM_BX_ALIGN_LOG2 +# define ARM_BX_ALIGN_LOG2 2 +#endif + +/* An OS-specific arm-features.h file may define ARM_NO_INDEX_REGISTER to + indicate that the two-register addressing modes must never be used. */ + +#endif /* arm-features.h */ diff --git a/libm/arm/fclrexcpt.c b/libm/arm/fclrexcpt.c new file mode 100644 index 000000000..81de94271 --- /dev/null +++ b/libm/arm/fclrexcpt.c @@ -0,0 +1,41 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "arm-features.h" + + +int +feclearexcept (int excepts) +{ + fpu_control_t fpscr, new_fpscr; + + /* Fail if a VFP unit isn't present unless nothing needs to be done. */ + if (!ARM_HAVE_VFP) + return (excepts != 0); + + _FPU_GETCW (fpscr); + excepts &= FE_ALL_EXCEPT; + new_fpscr = fpscr & ~excepts; + + /* Write new exception flags if changed. */ + if (new_fpscr != fpscr) + _FPU_SETCW (new_fpscr); + + return 0; +} diff --git a/libm/arm/fedisblxcpt.c b/libm/arm/fedisblxcpt.c new file mode 100644 index 000000000..c507e80b4 --- /dev/null +++ b/libm/arm/fedisblxcpt.c @@ -0,0 +1,41 @@ +/* Disable floating-point exceptions. + Copyright (C) 2001-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "arm-features.h" + + +int +fedisableexcept (int excepts) +{ + fpu_control_t fpscr, new_fpscr; + + /* Fail if a VFP unit isn't present. */ + if (!ARM_HAVE_VFP) + return -1; + + _FPU_GETCW (fpscr); + excepts &= FE_ALL_EXCEPT; + new_fpscr = fpscr & ~(excepts << FE_EXCEPT_SHIFT); + + /* Write new exceptions if changed. */ + if (new_fpscr != fpscr) + _FPU_SETCW (new_fpscr); + + return (fpscr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; +} diff --git a/libm/arm/feenablxcpt.c b/libm/arm/feenablxcpt.c new file mode 100644 index 000000000..41e8eb912 --- /dev/null +++ b/libm/arm/feenablxcpt.c @@ -0,0 +1,49 @@ +/* Enable floating-point exceptions. + Copyright (C) 2001-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "arm-features.h" + + +int +feenableexcept (int excepts) +{ + fpu_control_t fpscr, new_fpscr, updated_fpscr; + + /* Fail if a VFP unit isn't present. */ + if (!ARM_HAVE_VFP) + return -1; + + _FPU_GETCW (fpscr); + excepts &= FE_ALL_EXCEPT; + new_fpscr = fpscr | (excepts << FE_EXCEPT_SHIFT); + + if (new_fpscr != fpscr) + { + _FPU_SETCW (new_fpscr); + + /* Not all VFP architectures support trapping exceptions, so + test whether the relevant bits were set and fail if not. */ + _FPU_GETCW (updated_fpscr); + + if (new_fpscr & ~updated_fpscr) + return -1; + } + + return (fpscr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; +} diff --git a/libm/arm/fegetenv.c b/libm/arm/fegetenv.c new file mode 100644 index 000000000..a9f63f5c9 --- /dev/null +++ b/libm/arm/fegetenv.c @@ -0,0 +1,35 @@ +/* Store current floating-point environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "arm-features.h" + + +int +fegetenv (fenv_t *envp) +{ + fpu_control_t fpscr; + + /* Fail if a VFP unit isn't present. */ + if (!ARM_HAVE_VFP) + return 1; + + _FPU_GETCW (fpscr); + envp->__cw = fpscr; + return 0; +} diff --git a/libm/arm/fegetexcept.c b/libm/arm/fegetexcept.c new file mode 100644 index 000000000..5dd8e144b --- /dev/null +++ b/libm/arm/fegetexcept.c @@ -0,0 +1,35 @@ +/* Get floating-point exceptions. + Copyright (C) 2001-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "arm-features.h" + + +int +fegetexcept (void) +{ + fpu_control_t fpscr; + + /* Return with all exceptions disabled if a VFP unit isn't present. */ + if (!ARM_HAVE_VFP) + return 0; + + _FPU_GETCW (fpscr); + + return (fpscr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; +} diff --git a/libm/arm/fegetmode.c b/libm/arm/fegetmode.c new file mode 100644 index 000000000..bf2597353 --- /dev/null +++ b/libm/arm/fegetmode.c @@ -0,0 +1,28 @@ +/* Store current floating-point control modes. ARM version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "arm-features.h" + +int +fegetmode (femode_t *modep) +{ + if (ARM_HAVE_VFP) + _FPU_GETCW (*modep); + return 0; +} diff --git a/libm/arm/fegetround.c b/libm/arm/fegetround.c new file mode 100644 index 000000000..2f9320491 --- /dev/null +++ b/libm/arm/fegetround.c @@ -0,0 +1,42 @@ +/* Return current rounding direction. + Copyright (C) 2004-2025 Free Software Foundation, Inc. + + 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 "arm-features.h" +#include <fenv.h> +#include <fpu_control.h> + +/* Return the floating-point rounding mode. */ + +static inline int +get_rounding_mode (void) +{ + fpu_control_t fpscr; + + /* FE_TONEAREST is the only supported rounding mode + if a VFP unit isn't present. */ + if (!ARM_HAVE_VFP) + return FE_TONEAREST; + + _FPU_GETCW (fpscr); + return fpscr & _FPU_MASK_RM; +} + +int +fegetround (void) +{ + return get_rounding_mode (); +} diff --git a/libm/arm/feholdexcpt.c b/libm/arm/feholdexcpt.c new file mode 100644 index 000000000..3608931db --- /dev/null +++ b/libm/arm/feholdexcpt.c @@ -0,0 +1,31 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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_private.h" +#include "arm-features.h" + + +int +feholdexcept (fenv_t *envp) +{ + /* Fail if a VFP unit isn't present. */ + if (!ARM_HAVE_VFP) + return 1; + + libc_feholdexcept_vfp (envp); + return 0; +} diff --git a/libm/arm/fenv_private.h b/libm/arm/fenv_private.h new file mode 100644 index 000000000..566bf443c --- /dev/null +++ b/libm/arm/fenv_private.h @@ -0,0 +1,248 @@ +/* Private floating point rounding and exceptions handling. ARM VFP version. + Copyright (C) 2014-2025 Free Software Foundation, Inc. + + 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 ARM_FENV_PRIVATE_H +#define ARM_FENV_PRIVATE_H 1 + +#include <fenv.h> +#include <fpu_control.h> + +static __always_inline void +libc_feholdexcept_vfp (fenv_t *envp) +{ + fpu_control_t fpscr; + + _FPU_GETCW (fpscr); + envp->__cw = fpscr; + + /* Clear exception flags and set all exceptions to non-stop. */ + fpscr &= ~_FPU_MASK_EXCEPT; + _FPU_SETCW (fpscr); +} + +static __always_inline void +libc_fesetround_vfp (int round) +{ + fpu_control_t fpscr; + + _FPU_GETCW (fpscr); + + /* Set new rounding mode if different. */ + if (unlikely ((fpscr & _FPU_MASK_RM) != round)) + _FPU_SETCW ((fpscr & ~_FPU_MASK_RM) | round); +} + +static __always_inline void +libc_feholdexcept_setround_vfp (fenv_t *envp, int round) +{ + fpu_control_t fpscr; + + _FPU_GETCW (fpscr); + envp->__cw = fpscr; + + /* Clear exception flags, set all exceptions to non-stop, + and set new rounding mode. */ + fpscr &= ~(_FPU_MASK_EXCEPT | _FPU_MASK_RM); + _FPU_SETCW (fpscr | round); +} + +static __always_inline void +libc_feholdsetround_vfp (fenv_t *envp, int round) +{ + fpu_control_t fpscr; + + _FPU_GETCW (fpscr); + envp->__cw = fpscr; + + /* Set new rounding mode if different. */ + if (unlikely ((fpscr & _FPU_MASK_RM) != round)) + _FPU_SETCW ((fpscr & ~_FPU_MASK_RM) | round); +} + +static __always_inline void +libc_feresetround_vfp (fenv_t *envp) +{ + fpu_control_t fpscr, round; + + _FPU_GETCW (fpscr); + + /* Check whether rounding modes are different. */ + round = (envp->__cw ^ fpscr) & _FPU_MASK_RM; + + /* Restore the rounding mode if it was changed. */ + if (unlikely (round != 0)) + _FPU_SETCW (fpscr ^ round); +} + +static __always_inline int +libc_fetestexcept_vfp (int ex) +{ + fpu_control_t fpscr; + + _FPU_GETCW (fpscr); + return fpscr & ex & FE_ALL_EXCEPT; +} + +static __always_inline void +libc_fesetenv_vfp (const fenv_t *envp) +{ + fpu_control_t fpscr, new_fpscr; + + _FPU_GETCW (fpscr); + new_fpscr = envp->__cw; + + /* Write new FPSCR if different (ignoring NZCV flags). */ + if (unlikely (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0)) + _FPU_SETCW (new_fpscr); +} + +static __always_inline int +libc_feupdateenv_test_vfp (const fenv_t *envp, int ex) +{ + fpu_control_t fpscr, new_fpscr; + int excepts; + + _FPU_GETCW (fpscr); + + /* Merge current exception flags with the saved fenv. */ + excepts = fpscr & FE_ALL_EXCEPT; + new_fpscr = envp->__cw | excepts; + + /* Write new FPSCR if different (ignoring NZCV flags). */ + if (unlikely (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0)) + _FPU_SETCW (new_fpscr); + + /* Raise the exceptions if enabled in the new FP state. */ + if (unlikely (excepts & (new_fpscr >> FE_EXCEPT_SHIFT))) + feraiseexcept (excepts); + + return excepts & ex; +} + +static __always_inline void +libc_feupdateenv_vfp (const fenv_t *envp) +{ + libc_feupdateenv_test_vfp (envp, 0); +} + +static __always_inline void +libc_feholdsetround_vfp_ctx (struct rm_ctx *ctx, int r) +{ + fpu_control_t fpscr, round; + + _FPU_GETCW (fpscr); + ctx->updated_status = false; + ctx->env.__cw = fpscr; + + /* Check whether rounding modes are different. */ + round = (fpscr ^ r) & _FPU_MASK_RM; + + /* Set the rounding mode if changed. */ + if (unlikely (round != 0)) + { + ctx->updated_status = true; + _FPU_SETCW (fpscr ^ round); + } +} + +static __always_inline void +libc_feresetround_vfp_ctx (struct rm_ctx *ctx) +{ + /* Restore the rounding mode if updated. */ + if (unlikely (ctx->updated_status)) + { + fpu_control_t fpscr; + + _FPU_GETCW (fpscr); + fpscr = (fpscr & ~_FPU_MASK_RM) | (ctx->env.__cw & _FPU_MASK_RM); + _FPU_SETCW (fpscr); + } +} + +static __always_inline void +libc_fesetenv_vfp_ctx (struct rm_ctx *ctx) +{ + fpu_control_t fpscr, new_fpscr; + + _FPU_GETCW (fpscr); + new_fpscr = ctx->env.__cw; + + /* Write new FPSCR if different (ignoring NZCV flags). */ + if (unlikely (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0)) + _FPU_SETCW (new_fpscr); +} + +#ifndef __SOFTFP__ + +# define libc_feholdexcept libc_feholdexcept_vfp +# define libc_feholdexceptf libc_feholdexcept_vfp +# define libc_feholdexceptl libc_feholdexcept_vfp + +# define libc_fesetround libc_fesetround_vfp +# define libc_fesetroundf libc_fesetround_vfp +# define libc_fesetroundl libc_fesetround_vfp + +# define libc_feresetround libc_feresetround_vfp +# define libc_feresetroundf libc_feresetround_vfp +# define libc_feresetroundl libc_feresetround_vfp + +# define libc_feresetround_noex libc_fesetenv_vfp +# define libc_feresetround_noexf libc_fesetenv_vfp +# define libc_feresetround_noexl libc_fesetenv_vfp + +# define libc_feholdexcept_setround libc_feholdexcept_setround_vfp +# define libc_feholdexcept_setroundf libc_feholdexcept_setround_vfp +# define libc_feholdexcept_setroundl libc_feholdexcept_setround_vfp + +# define libc_feholdsetround libc_feholdsetround_vfp +# define libc_feholdsetroundf libc_feholdsetround_vfp +# define libc_feholdsetroundl libc_feholdsetround_vfp + +# define libc_fetestexcept libc_fetestexcept_vfp +# define libc_fetestexceptf libc_fetestexcept_vfp +# define libc_fetestexceptl libc_fetestexcept_vfp + +# define libc_fesetenv libc_fesetenv_vfp +# define libc_fesetenvf libc_fesetenv_vfp +# define libc_fesetenvl libc_fesetenv_vfp + +# define libc_feupdateenv libc_feupdateenv_vfp +# define libc_feupdateenvf libc_feupdateenv_vfp +# define libc_feupdateenvl libc_feupdateenv_vfp + +# define libc_feupdateenv_test libc_feupdateenv_test_vfp +# define libc_feupdateenv_testf libc_feupdateenv_test_vfp +# define libc_feupdateenv_testl libc_feupdateenv_test_vfp + +/* We have support for rounding mode context. */ +#define HAVE_RM_CTX 1 + +# define libc_feholdsetround_ctx libc_feholdsetround_vfp_ctx +# define libc_feresetround_ctx libc_feresetround_vfp_ctx +# define libc_feresetround_noex_ctx libc_fesetenv_vfp_ctx + +# define libc_feholdsetroundf_ctx libc_feholdsetround_vfp_ctx +# define libc_feresetroundf_ctx libc_feresetround_vfp_ctx +# define libc_feresetround_noexf_ctx libc_fesetenv_vfp_ctx + +# define libc_feholdsetroundl_ctx libc_feholdsetround_vfp_ctx +# define libc_feresetroundl_ctx libc_feresetround_vfp_ctx +# define libc_feresetround_noexl_ctx libc_fesetenv_vfp_ctx + +#endif + +#endif /* ARM_FENV_PRIVATE_H */ diff --git a/libm/arm/fesetenv.c b/libm/arm/fesetenv.c new file mode 100644 index 000000000..4675dbe88 --- /dev/null +++ b/libm/arm/fesetenv.c @@ -0,0 +1,62 @@ +/* Install given floating-point environment. + Copyright (C) 2004-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "arm-features.h" + + +int +fesetenv (const fenv_t *envp) +{ + fpu_control_t fpscr, new_fpscr, updated_fpscr; + + /* Fail if a VFP unit isn't present. */ + if (!ARM_HAVE_VFP) + return 1; + + _FPU_GETCW (fpscr); + + if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV)) + { + /* The new FPSCR is valid, so don't merge the reserved flags. */ + new_fpscr = envp->__cw; + + /* Write new FPSCR if different (ignoring NZCV flags). */ + if (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0) + _FPU_SETCW (new_fpscr); + + return 0; + } + + /* Preserve the reserved FPSCR flags. */ + new_fpscr = fpscr & _FPU_RESERVED; + new_fpscr |= (envp == FE_DFL_ENV) ? _FPU_DEFAULT : _FPU_IEEE; + + if (((new_fpscr ^ fpscr) & ~_FPU_MASK_NZCV) != 0) + { + _FPU_SETCW (new_fpscr); + + /* Not all VFP architectures support trapping exceptions, so + test whether the relevant bits were set and fail if not. */ + _FPU_GETCW (updated_fpscr); + + return new_fpscr & ~updated_fpscr; + } + + return 0; +} diff --git a/libm/arm/fesetexcept.c b/libm/arm/fesetexcept.c new file mode 100644 index 000000000..03338c783 --- /dev/null +++ b/libm/arm/fesetexcept.c @@ -0,0 +1,37 @@ +/* Set given exception flags. ARM version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "arm-features.h" + +int +fesetexcept (int excepts) +{ + fpu_control_t fpscr, new_fpscr; + + /* Fail if a VFP unit isn't present unless nothing needs to be done. */ + if (!ARM_HAVE_VFP) + return (excepts != 0); + + _FPU_GETCW (fpscr); + new_fpscr = fpscr | (excepts & FE_ALL_EXCEPT); + if (new_fpscr != fpscr) + _FPU_SETCW (new_fpscr); + + return 0; +} diff --git a/libm/arm/fesetmode.c b/libm/arm/fesetmode.c new file mode 100644 index 000000000..7919022b0 --- /dev/null +++ b/libm/arm/fesetmode.c @@ -0,0 +1,44 @@ +/* Install given floating-point control modes. ARM version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "arm-features.h" + +/* NZCV flags, QC bit, IDC bit and bits for IEEE exception status. */ +#define FPU_STATUS_BITS 0xf800009f + +int +fesetmode (const femode_t *modep) +{ + fpu_control_t fpscr, new_fpscr; + + if (!ARM_HAVE_VFP) + /* Nothing to do. */ + return 0; + + _FPU_GETCW (fpscr); + if (modep == FE_DFL_MODE) + new_fpscr = (fpscr & (_FPU_RESERVED | FPU_STATUS_BITS)) | _FPU_DEFAULT; + else + new_fpscr = (fpscr & FPU_STATUS_BITS) | (*modep & ~FPU_STATUS_BITS); + + if (((new_fpscr ^ fpscr) & ~_FPU_MASK_NZCV) != 0) + _FPU_SETCW (new_fpscr); + + return 0; +} diff --git a/libm/arm/fesetround.c b/libm/arm/fesetround.c new file mode 100644 index 000000000..1cb6b366c --- /dev/null +++ b/libm/arm/fesetround.c @@ -0,0 +1,35 @@ +/* Set current rounding direction. + Copyright (C) 2004-2025 Free Software Foundation, Inc. + + 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_private.h" +#include "arm-features.h" + + +int +fesetround (int round) +{ + /* FE_TONEAREST is the only supported rounding mode + if a VFP unit isn't present. */ + if (!ARM_HAVE_VFP) + return (round == FE_TONEAREST) ? 0 : 1; + + if (round & ~_FPU_MASK_RM) + return 1; + + libc_fesetround_vfp (round); + return 0; +} diff --git a/libm/arm/feupdateenv.c b/libm/arm/feupdateenv.c new file mode 100644 index 000000000..a246b865b --- /dev/null +++ b/libm/arm/feupdateenv.c @@ -0,0 +1,73 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "arm-features.h" + + +int +feupdateenv (const fenv_t *envp) +{ + fpu_control_t fpscr, new_fpscr, updated_fpscr; + int excepts; + + /* Fail if a VFP unit isn't present. */ + if (!ARM_HAVE_VFP) + return 1; + + _FPU_GETCW (fpscr); + excepts = fpscr & FE_ALL_EXCEPT; + + if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV)) + { + /* Merge current exception flags with the saved fenv. */ + new_fpscr = envp->__cw | excepts; + + /* Write new FPSCR if different (ignoring NZCV flags). */ + if (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0) + _FPU_SETCW (new_fpscr); + + /* Raise the exceptions if enabled in the new FP state. */ + if (excepts & (new_fpscr >> FE_EXCEPT_SHIFT)) + return feraiseexcept (excepts); + + return 0; + } + + /* Preserve the reserved FPSCR flags. */ + new_fpscr = fpscr & (_FPU_RESERVED | FE_ALL_EXCEPT); + new_fpscr |= (envp == FE_DFL_ENV) ? _FPU_DEFAULT : _FPU_IEEE; + + if (((new_fpscr ^ fpscr) & ~_FPU_MASK_NZCV) != 0) + { + _FPU_SETCW (new_fpscr); + + /* Not all VFP architectures support trapping exceptions, so + test whether the relevant bits were set and fail if not. */ + _FPU_GETCW (updated_fpscr); + + if (new_fpscr & ~updated_fpscr) + return 1; + } + + /* Raise the exceptions if enabled in the new FP state. */ + if (excepts & (new_fpscr >> FE_EXCEPT_SHIFT)) + return feraiseexcept (excepts); + + return 0; +} diff --git a/libm/arm/fgetexcptflg.c b/libm/arm/fgetexcptflg.c new file mode 100644 index 000000000..2ef835fd4 --- /dev/null +++ b/libm/arm/fgetexcptflg.c @@ -0,0 +1,31 @@ +/* Store current representation for exceptions. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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_private.h" +#include "arm-features.h" + + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + /* Fail if a VFP unit isn't present. */ + if (!ARM_HAVE_VFP) + return 1; + + *flagp = libc_fetestexcept_vfp (excepts); + return 0; +} diff --git a/libm/arm/fraiseexcpt.c b/libm/arm/fraiseexcpt.c new file mode 100644 index 000000000..91a5d6308 --- /dev/null +++ b/libm/arm/fraiseexcpt.c @@ -0,0 +1,103 @@ +/* Raise given exceptions. + Copyright (C) 2004-2025 Free Software Foundation, Inc. + + 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 <fpu_control.h> +#include <fenv.h> +#include <float.h> +#include "arm-features.h" + + +int +feraiseexcept (int excepts) +{ + /* Fail if a VFP unit isn't present unless nothing needs to be done. */ + if (!ARM_HAVE_VFP) + return (excepts != 0); + else + { + fpu_control_t fpscr; + const float fp_zero = 0.0, fp_one = 1.0, fp_max = FLT_MAX, + fp_min = FLT_MIN, fp_1e32 = 1.0e32f, fp_two = 2.0, + fp_three = 3.0; + + /* Raise exceptions represented by EXPECTS. But we must raise only + one signal at a time. It is important that if the overflow/underflow + exception and the inexact exception are given at the same time, + the overflow/underflow exception follows the inexact exception. After + each exception we read from the fpscr, to force the exception to be + raised immediately. */ + + /* There are additional complications because this file may be compiled + without VFP support enabled, and we also can't assume that the + assembler has VFP instructions enabled. To get around this we use the + generic coprocessor mnemonics and avoid asking GCC to put float values + in VFP registers. */ + + /* First: invalid exception. */ + if (FE_INVALID & excepts) + __asm__ __volatile__ ( + "ldc p10, cr0, %1\n\t" /* flds s0, %1 */ + "cdp p10, 8, cr0, cr0, cr0, 0\n\t" /* fdivs s0, s0, s0 */ + "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */ + : "m" (fp_zero) + : "s0"); + + /* Next: division by zero. */ + if (FE_DIVBYZERO & excepts) + __asm__ __volatile__ ( + "ldc p10, cr0, %1\n\t" /* flds s0, %1 */ + "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */ + "cdp p10, 8, cr0, cr0, cr0, 1\n\t" /* fdivs s0, s0, s1 */ + "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */ + : "m" (fp_one), "m" (fp_zero) + : "s0", "s1"); + + /* Next: overflow. */ + if (FE_OVERFLOW & excepts) + /* There's no way to raise overflow without also raising inexact. */ + __asm__ __volatile__ ( + "ldc p10, cr0, %1\n\t" /* flds s0, %1 */ + "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */ + "cdp p10, 3, cr0, cr0, cr0, 1\n\t" /* fadds s0, s0, s1 */ + "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */ + : "m" (fp_max), "m" (fp_1e32) + : "s0", "s1"); + + /* Next: underflow. */ + if (FE_UNDERFLOW & excepts) + __asm__ __volatile__ ( + "ldc p10, cr0, %1\n\t" /* flds s0, %1 */ + "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */ + "cdp p10, 8, cr0, cr0, cr0, 1\n\t" /* fdivs s0, s0, s1 */ + "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */ + : "m" (fp_min), "m" (fp_three) + : "s0", "s1"); + + /* Last: inexact. */ + if (FE_INEXACT & excepts) + __asm__ __volatile__ ( + "ldc p10, cr0, %1\n\t" /* flds s0, %1 */ + "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */ + "cdp p10, 8, cr0, cr0, cr0, 1\n\t" /* fdivs s0, s0, s1 */ + "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */ + : "m" (fp_two), "m" (fp_three) + : "s0", "s1"); + + /* Success. */ + return 0; + } +} diff --git a/libm/arm/fsetexcptflg.c b/libm/arm/fsetexcptflg.c new file mode 100644 index 000000000..343b33af9 --- /dev/null +++ b/libm/arm/fsetexcptflg.c @@ -0,0 +1,44 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "arm-features.h" + + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fpu_control_t fpscr, new_fpscr; + + /* Fail if a VFP unit isn't present unless nothing needs to be done. */ + if (!ARM_HAVE_VFP) + return (excepts != 0); + + _FPU_GETCW (fpscr); + excepts &= FE_ALL_EXCEPT; + + /* Set the desired exception mask. */ + new_fpscr = fpscr & ~excepts; + new_fpscr |= *flagp & excepts; + + /* Write new exception flags if changed. */ + if (new_fpscr != fpscr) + _FPU_SETCW (new_fpscr); + + return 0; +} diff --git a/libm/arm/ftestexcept.c b/libm/arm/ftestexcept.c new file mode 100644 index 000000000..8b836d97d --- /dev/null +++ b/libm/arm/ftestexcept.c @@ -0,0 +1,30 @@ +/* Test exception in current environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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_private.h" +#include "arm-features.h" + + +int +fetestexcept (int excepts) +{ + /* Return no exception flags if a VFP unit isn't present. */ + if (!ARM_HAVE_VFP) + return 0; + + return libc_fetestexcept_vfp (excepts); +} diff --git a/libm/cexp.c b/libm/cexp.c index 87512b7c5..a08d12d4e 100644 --- a/libm/cexp.c +++ b/libm/cexp.c @@ -38,10 +38,10 @@ libm_hidden_proto(cexpf) __complex__ float cexpf(__complex__ float z) { __complex__ float ret; - double r_exponent = exp(__real__ z); + double r_exponent = exp((double)__real__ z); - __real__ ret = r_exponent * cosf(__imag__ z); - __imag__ ret = r_exponent * sinf(__imag__ z); + __real__ ret = r_exponent * (double) cosf(__imag__ z); + __imag__ ret = r_exponent * (double) sinf(__imag__ z); return ret; } diff --git a/libm/csky/Makefile.arch b/libm/csky/Makefile.arch new file mode 100644 index 000000000..bd38690be --- /dev/null +++ b/libm/csky/Makefile.arch @@ -0,0 +1,16 @@ +# Makefile for uClibc-ng +# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + +ifeq ($(UCLIBC_HAS_FENV),y) +libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c) +libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC)) +endif + +libm_ARCH_OBJS:=$(libm_ARCH_OBJ) + +ifeq ($(DOPIC),y) +libm-a-y+=$(libm_ARCH_OBJS:.o=.os) +else +libm-a-y+=$(libm_ARCH_OBJS) +endif +libm-so-y+=$(libm_ARCH_OBJS:.o=.os) diff --git a/libm/csky/fclrexcpt.c b/libm/csky/fclrexcpt.c new file mode 100644 index 000000000..8f8acef16 --- /dev/null +++ b/libm/csky/fclrexcpt.c @@ -0,0 +1,40 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_libc.h" +#include <fpu_control.h> + +int +feclearexcept (int excepts) +{ + int fpsr; + + /* Mask out unsupported bits/exceptions. */ + excepts &= FE_ALL_EXCEPT; + + /* Read the complete control word. */ + _FPU_GETFPSR (fpsr); + + /* Clear the relevant bits. */ + fpsr &= ~(excepts | (excepts << CAUSE_SHIFT)); + + /* Put the new data in effect. */ + _FPU_SETFPSR (fpsr); + + return 0; +} diff --git a/libm/csky/fedisblxcpt.c b/libm/csky/fedisblxcpt.c new file mode 100644 index 000000000..e518968ab --- /dev/null +++ b/libm/csky/fedisblxcpt.c @@ -0,0 +1,40 @@ +/* Disable floating-point exceptions. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_libc.h" +#include <fpu_control.h> + +int +fedisableexcept (int excepts) +{ + unsigned int new_exc, old_exc; + + /* Get the current control word. */ + _FPU_GETCW (new_exc); + + old_exc = (new_exc & ENABLE_MASK) >> ENABLE_SHIFT; + + /* Get the except disable mask. */ + excepts &= FE_ALL_EXCEPT; + new_exc &= ~(excepts << ENABLE_SHIFT); + + /* Put the new data in effect. */ + _FPU_SETCW (new_exc); + + return old_exc; +} diff --git a/libm/csky/feenablxcpt.c b/libm/csky/feenablxcpt.c new file mode 100644 index 000000000..90c495080 --- /dev/null +++ b/libm/csky/feenablxcpt.c @@ -0,0 +1,39 @@ +/* Enable floating-point exceptions. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_libc.h" +#include <fpu_control.h> + +int +feenableexcept (int excepts) +{ + unsigned int new_exc, old_exc; + + /* Get the current control word. */ + _FPU_GETCW (new_exc); + + old_exc = (new_exc & ENABLE_MASK) >> ENABLE_SHIFT; + + excepts &= FE_ALL_EXCEPT; + + new_exc |= excepts << ENABLE_SHIFT; + + _FPU_SETCW (new_exc); + + return old_exc; +} diff --git a/libm/csky/fegetenv.c b/libm/csky/fegetenv.c new file mode 100644 index 000000000..d98982fc1 --- /dev/null +++ b/libm/csky/fegetenv.c @@ -0,0 +1,33 @@ +/* Store current floating-point environment. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetenv (fenv_t *envp) +{ + unsigned int fpcr; + unsigned int fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + envp->__fpcr = fpcr; + envp->__fpsr = fpsr; + + return 0; +} diff --git a/libm/csky/fegetexcept.c b/libm/csky/fegetexcept.c new file mode 100644 index 000000000..339f35923 --- /dev/null +++ b/libm/csky/fegetexcept.c @@ -0,0 +1,31 @@ +/* Get enabled floating-point exceptions. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_libc.h" +#include <fpu_control.h> + +int +fegetexcept (void) +{ + unsigned int exc; + + /* Get the current control word. */ + _FPU_GETCW (exc); + + return (exc & ENABLE_MASK) >> ENABLE_SHIFT; +} diff --git a/libm/csky/fegetmode.c b/libm/csky/fegetmode.c new file mode 100644 index 000000000..09d8282dd --- /dev/null +++ b/libm/csky/fegetmode.c @@ -0,0 +1,27 @@ +/* Store current floating-point control modes. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetmode (femode_t *modep) +{ + _FPU_GETCW (*modep); + + return 0; +} diff --git a/libm/csky/fegetround.c b/libm/csky/fegetround.c new file mode 100644 index 000000000..e68775af3 --- /dev/null +++ b/libm/csky/fegetround.c @@ -0,0 +1,30 @@ +/* Return current rounding direction. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetround (void) +{ + unsigned int cw; + + /* Get control word. */ + _FPU_GETCW (cw); + + return cw & __FE_ROUND_MASK; +} diff --git a/libm/csky/feholdexcpt.c b/libm/csky/feholdexcpt.c new file mode 100644 index 000000000..456af5eb1 --- /dev/null +++ b/libm/csky/feholdexcpt.c @@ -0,0 +1,30 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "fenv_libc.h" +#include "fenv_private.h" + +#include <stdio.h> + +int +feholdexcept (fenv_t *envp) +{ + libc_feholdexcept_vfp (envp); + return 0; +} diff --git a/libm/csky/fenv_libc.h b/libm/csky/fenv_libc.h new file mode 100644 index 000000000..44e89812d --- /dev/null +++ b/libm/csky/fenv_libc.h @@ -0,0 +1,29 @@ +/* fpu registers environment. C-SKY version. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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_LIBC_H +#define _FENV_LIBC_H 1 + +/* Mask for enabling exceptions and for the CAUSE bits. */ +#define ENABLE_MASK 0x0003FU +#define CAUSE_MASK 0x3F000U + +/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits. */ +#define ENABLE_SHIFT 0 +#define CAUSE_SHIFT 8 + +#endif /* fenv_libc.h */ diff --git a/libm/csky/fenv_private.h b/libm/csky/fenv_private.h new file mode 100644 index 000000000..f0f48a88a --- /dev/null +++ b/libm/csky/fenv_private.h @@ -0,0 +1,277 @@ +/* Private floating point rounding and exceptions handling. C-SKY version. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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 CSKY_FENV_PRIVATE_H +#define CSKY_FENV_PRIVATE_H 1 + +#include <fenv.h> +#include <fpu_control.h> +#include "fenv_libc.h" + +static __always_inline void +libc_feholdexcept_vfp (fenv_t *envp) +{ + fpu_control_t fpsr, fpcr; + + _FPU_GETCW (fpcr); + envp->__fpcr = fpcr; + + _FPU_GETFPSR (fpsr); + envp->__fpsr = fpsr; + + /* Now set all exceptions to non-stop. */ + fpcr &= ~FE_ALL_EXCEPT; + + /* And clear all exception flags. */ + fpsr &= ~(FE_ALL_EXCEPT << CAUSE_SHIFT); + + _FPU_SETFPSR (fpsr); + + _FPU_SETCW (fpcr); +} + +static __always_inline void +libc_fesetround_vfp (int round) +{ + fpu_control_t fpcr; + + _FPU_GETCW (fpcr); + + /* Set new rounding mode if different. */ + if (unlikely ((fpcr & FE_DOWNWARD) != round)) + _FPU_SETCW ((fpcr & ~FE_DOWNWARD) | round); +} + +static __always_inline void +libc_feholdexcept_setround_vfp (fenv_t *envp, int round) +{ + fpu_control_t fpsr, fpcr; + + _FPU_GETCW (fpcr); + envp->__fpcr = fpcr; + + _FPU_GETFPSR (fpsr); + envp->__fpsr = fpsr; + + /* Clear exception flags, set all exceptions to non-stop, + and set new rounding mode. */ + fpsr &= ~(FE_ALL_EXCEPT << CAUSE_SHIFT); + _FPU_SETFPSR (fpsr); + + fpcr &= ~(FE_ALL_EXCEPT | FE_DOWNWARD); + _FPU_SETCW (fpcr | round); +} + +static __always_inline void +libc_feholdsetround_vfp (fenv_t *envp, int round) +{ + fpu_control_t fpcr; + + _FPU_GETCW (fpcr); + envp->__fpcr = fpcr; + + /* Set new rounding mode if different. */ + if (unlikely ((fpcr & FE_DOWNWARD) != round)) + _FPU_SETCW ((fpcr & ~FE_DOWNWARD) | round); +} + +static __always_inline void +libc_feresetround_vfp (fenv_t *envp) +{ + fpu_control_t fpcr, round; + + _FPU_GETCW (fpcr); + + /* Check whether rounding modes are different. */ + round = (envp->__fpcr ^ fpcr) & FE_DOWNWARD; + + /* Restore the rounding mode if it was changed. */ + if (unlikely (round != 0)) + _FPU_SETCW (fpcr ^ round); +} + +static __always_inline int +libc_fetestexcept_vfp (int ex) +{ + fpu_control_t fpsr; + + _FPU_GETFPSR (fpsr); + fpsr = fpsr >> CAUSE_SHIFT; + return fpsr & ex & FE_ALL_EXCEPT; +} + +static __always_inline void +libc_fesetenv_vfp (const fenv_t *envp) +{ + fpu_control_t fpcr, fpsr, new_fpcr, new_fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + + new_fpcr = envp->__fpcr; + new_fpsr = envp->__fpsr; + + if (unlikely (fpsr ^ new_fpsr) != 0) + _FPU_SETFPSR (new_fpsr); + + if (unlikely (fpcr ^ new_fpcr) != 0) + _FPU_SETCW (new_fpcr); +} + +static __always_inline int +libc_feupdateenv_test_vfp (const fenv_t *envp, int ex) +{ + fpu_control_t fpcr, fpsr, new_fpcr, new_fpsr, excepts; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + + /* Merge current exception flags with the saved fenv. */ + excepts = (fpsr >> CAUSE_SHIFT) & FE_ALL_EXCEPT; + new_fpcr = envp->__fpcr; + new_fpsr = envp->__fpsr | (excepts << CAUSE_SHIFT); + + /* Write FCR and FESR if different. */ + if (unlikely (fpsr ^ new_fpsr) != 0) + _FPU_SETFPSR (new_fpsr); + + if (unlikely (fpcr ^ new_fpcr) != 0) + _FPU_SETCW (new_fpcr); + + /* Raise the exceptions if enabled in the new FP state. */ + if (unlikely (excepts & new_fpcr)) + feraiseexcept (excepts); + + return excepts & ex; +} + +static __always_inline void +libc_feupdateenv_vfp (const fenv_t *envp) +{ + libc_feupdateenv_test_vfp (envp, 0); +} + +static __always_inline void +libc_feholdsetround_vfp_ctx (struct rm_ctx *ctx, int r) +{ + fpu_control_t fpcr, fpsr, round; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + ctx->updated_status = false; + ctx->env.__fpcr = fpcr; + ctx->env.__fpsr = fpsr; + + /* Check whether rounding modes are different. */ + round = (fpcr ^ r) & FE_DOWNWARD; + + /* Set the rounding mode if changed. */ + if (unlikely (round != 0)) + { + ctx->updated_status = true; + _FPU_SETCW (fpcr ^ round); + } +} + +static __always_inline void +libc_feresetround_vfp_ctx (struct rm_ctx *ctx) +{ + /* Restore the rounding mode if updated. */ + if (unlikely (ctx->updated_status)) + { + fpu_control_t fpcr; + + _FPU_GETCW (fpcr); + fpcr = (fpcr & ~FE_DOWNWARD) | (ctx->env.__fpcr & FE_DOWNWARD); + _FPU_SETCW (fpcr); + } +} + +static __always_inline void +libc_fesetenv_vfp_ctx (struct rm_ctx *ctx) +{ + fpu_control_t fpcr, fpsr, new_fpcr, new_fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + + new_fpcr = ctx->env.__fpcr; + new_fpsr = ctx->env.__fpsr; + + if (unlikely (fpsr ^ new_fpsr) != 0) + _FPU_SETFPSR (new_fpsr); + + if (unlikely (fpcr ^ new_fpcr) != 0) + _FPU_SETCW (new_fpcr); +} + +#define libc_feholdexcept libc_feholdexcept_vfp +#define libc_feholdexceptf libc_feholdexcept_vfp +#define libc_feholdexceptl libc_feholdexcept_vfp + +#define libc_fesetround libc_fesetround_vfp +#define libc_fesetroundf libc_fesetround_vfp +#define libc_fesetroundl libc_fesetround_vfp + +#define libc_feresetround libc_feresetround_vfp +#define libc_feresetroundf libc_feresetround_vfp +#define libc_feresetroundl libc_feresetround_vfp + +#define libc_feresetround_noex libc_fesetenv_vfp +#define libc_feresetround_noexf libc_fesetenv_vfp +#define libc_feresetround_noexl libc_fesetenv_vfp + +#define libc_feholdexcept_setround libc_feholdexcept_setround_vfp +#define libc_feholdexcept_setroundf libc_feholdexcept_setround_vfp +#define libc_feholdexcept_setroundl libc_feholdexcept_setround_vfp + +#define libc_feholdsetround libc_feholdsetround_vfp +#define libc_feholdsetroundf libc_feholdsetround_vfp +#define libc_feholdsetroundl libc_feholdsetround_vfp + +#define libc_fetestexcept libc_fetestexcept_vfp +#define libc_fetestexceptf libc_fetestexcept_vfp +#define libc_fetestexceptl libc_fetestexcept_vfp + +#define libc_fesetenv libc_fesetenv_vfp +#define libc_fesetenvf libc_fesetenv_vfp +#define libc_fesetenvl libc_fesetenv_vfp + +#define libc_feupdateenv libc_feupdateenv_vfp +#define libc_feupdateenvf libc_feupdateenv_vfp +#define libc_feupdateenvl libc_feupdateenv_vfp + +#define libc_feupdateenv_test libc_feupdateenv_test_vfp +#define libc_feupdateenv_testf libc_feupdateenv_test_vfp +#define libc_feupdateenv_testl libc_feupdateenv_test_vfp + +/* We have support for rounding mode context. */ +#define HAVE_RM_CTX 1 + +#define libc_feholdsetround_ctx libc_feholdsetround_vfp_ctx +#define libc_feresetround_ctx libc_feresetround_vfp_ctx +#define libc_feresetround_noex_ctx libc_fesetenv_vfp_ctx + +#define libc_feholdsetroundf_ctx libc_feholdsetround_vfp_ctx +#define libc_feresetroundf_ctx libc_feresetround_vfp_ctx +#define libc_feresetround_noexf_ctx libc_fesetenv_vfp_ctx + +#define libc_feholdsetroundl_ctx libc_feholdsetround_vfp_ctx +#define libc_feresetroundl_ctx libc_feresetround_vfp_ctx +#define libc_feresetround_noexl_ctx libc_fesetenv_vfp_ctx + +#endif /* CSKY_FENV_PRIVATE_H */ diff --git a/libm/csky/fesetenv.c b/libm/csky/fesetenv.c new file mode 100644 index 000000000..96b961598 --- /dev/null +++ b/libm/csky/fesetenv.c @@ -0,0 +1,55 @@ +/* Install given floating-point environment. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetenv (const fenv_t *envp) +{ + unsigned int fpcr; + unsigned int fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + + fpcr &= _FPU_RESERVED; + fpsr &= _FPU_FPSR_RESERVED; + + if (envp == FE_DFL_ENV) + { + fpcr |= _FPU_DEFAULT; + fpsr |= _FPU_FPSR_DEFAULT; + } + else if (envp == FE_NOMASK_ENV) + { + fpcr |= _FPU_FPCR_IEEE; + fpsr |= _FPU_FPSR_IEEE; + } + else + { + fpcr |= envp->__fpcr & ~_FPU_RESERVED; + fpsr |= envp->__fpsr & ~_FPU_FPSR_RESERVED; + } + + _FPU_SETFPSR (fpsr); + + _FPU_SETCW (fpcr); + + /* Success. */ + return 0; +} diff --git a/libm/csky/fesetexcept.c b/libm/csky/fesetexcept.c new file mode 100644 index 000000000..940322197 --- /dev/null +++ b/libm/csky/fesetexcept.c @@ -0,0 +1,32 @@ +/* Set given exception flags. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "fenv_libc.h" + +int +fesetexcept (int excepts) +{ + fpu_control_t fpsr, new_fpsr; + _FPU_GETFPSR (fpsr); + new_fpsr = fpsr | ((excepts & FE_ALL_EXCEPT) << CAUSE_SHIFT); + if (new_fpsr != fpsr) + _FPU_SETFPSR (new_fpsr); + + return 0; +} diff --git a/libm/csky/fesetmode.c b/libm/csky/fesetmode.c new file mode 100644 index 000000000..eddd2d401 --- /dev/null +++ b/libm/csky/fesetmode.c @@ -0,0 +1,32 @@ +/* Install given floating-point control modes. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetmode (const femode_t *modep) +{ + femode_t mode; + if (modep == FE_DFL_MODE) + mode = _FPU_DEFAULT; + else + mode = *modep; + _FPU_SETCW (mode); + + return 0; +} diff --git a/libm/csky/fesetround.c b/libm/csky/fesetround.c new file mode 100644 index 000000000..15a4b7c7e --- /dev/null +++ b/libm/csky/fesetround.c @@ -0,0 +1,28 @@ +/* Set current rounding direction. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "fenv_private.h" + +#include <stdio.h> +int +fesetround (int round) +{ + libc_fesetround_vfp (round); + return 0; +} diff --git a/libm/csky/feupdateenv.c b/libm/csky/feupdateenv.c new file mode 100644 index 000000000..91e627ad2 --- /dev/null +++ b/libm/csky/feupdateenv.c @@ -0,0 +1,42 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "fenv_libc.h" +#include "fenv_private.h" +#include <stdio.h> + +int +feupdateenv (const fenv_t *envp) +{ + int temp; + + /* Save current exceptions. */ + _FPU_GETFPSR (temp); + temp = (temp >> CAUSE_SHIFT) & FE_ALL_EXCEPT; + /* Install new environment. */ + fesetenv (envp); + + /* Raise the saved exception. Incidentally for us the implementation + defined format of the values in objects of type fexcept_t is the + same as the ones specified using the FE_* constants. */ + feraiseexcept (temp); + + /* Success. */ + return 0; +} diff --git a/libm/csky/fgetexcptflg.c b/libm/csky/fgetexcptflg.c new file mode 100644 index 000000000..c400a2c1f --- /dev/null +++ b/libm/csky/fgetexcptflg.c @@ -0,0 +1,31 @@ +/* Store current representation for exceptions. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "fenv_libc.h" +#include "fenv_private.h" +#include <stdio.h> + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + *flagp = libc_fetestexcept_vfp (excepts); + + /* Success. */ + return 0; +} diff --git a/libm/csky/fraiseexcpt.c b/libm/csky/fraiseexcpt.c new file mode 100644 index 000000000..31cd32f2c --- /dev/null +++ b/libm/csky/fraiseexcpt.c @@ -0,0 +1,122 @@ +/* Raise given exceptions. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_libc.h" +#include <fpu_control.h> +#include <float.h> +#include <math.h> + +int +feraiseexcept (int excepts) +{ + /* Raise exceptions represented by EXCEPTS. But we must raise only one + signal at a time. It is important that if the overflow/underflow + exception and the divide by zero exception are given at the same + time, the overflow/underflow exception follows the divide by zero + exception. */ + +# ifndef __csky_fpuv1__ + /* First: invalid exception. */ + if (FE_INVALID & excepts) + { + /* One example of a invalid operation is 0 * Infinity. */ + float x = HUGE_VALF, y = 0.0f; + __asm__ __volatile__ ("fmuls %0, %0, %1" : "+v" (x) : "v" (y)); + } + + /* Next: division by zero. */ + if (FE_DIVBYZERO & excepts) + { + float x = 1.0f, y = 0.0f; + __asm__ __volatile__ ("fdivs %0, %0, %1" : "+v" (x) : "v" (y)); + } + + /* Next: overflow. */ + if (FE_OVERFLOW & excepts) + { + float x = FLT_MAX; + __asm__ __volatile__ ("fmuls %0, %0, %0" : "+v" (x)); + } + /* Next: underflow. */ + if (FE_UNDERFLOW & excepts) + { + float x = -FLT_MIN; + + __asm__ __volatile__ ("fmuls %0, %0, %0" : "+v" (x)); + } + + /* Last: inexact. */ + if (FE_INEXACT & excepts) + { + float x = 1.0f, y = 3.0f; + __asm__ __volatile__ ("fdivs %0, %0, %1" : "+v" (x) : "v" (y)); + } + + if (__FE_DENORMAL & excepts) + { + double x = 4.9406564584124654e-324; + __asm__ __volatile__ ("fstod %0, %0" : "+v" (x)); + } +# else + int tmp = 0; + /* First: invalid exception. */ + if (FE_INVALID & excepts) + { + /* One example of a invalid operation is 0 * Infinity. */ + float x = HUGE_VALF, y = 0.0f; + __asm__ __volatile__ ("fmuls %0, %0, %2, %1" + : "+f" (x), "+r"(tmp) : "f" (y)); + } + + /* Next: division by zero. */ + if (FE_DIVBYZERO & excepts) + { + float x = 1.0f, y = 0.0f; + __asm__ __volatile__ ("fdivs %0, %0, %2, %1" + : "+f" (x), "+r"(tmp) : "f" (y)); + } + + /* Next: overflow. */ + if (FE_OVERFLOW & excepts) + { + float x = FLT_MAX, y = FLT_MAX; + __asm__ __volatile__ ("fmuls %0, %0, %2, %1" + : "+f" (x), "+r"(tmp) : "f" (y)); + } + + /* Next: underflow. */ + if (FE_UNDERFLOW & excepts) + { + float x = -FLT_MIN, y = -FLT_MIN; + + __asm__ __volatile__ ("fmuls %0, %0, %2, %1" + : "+f" (x), "+r"(tmp) : "f" (y)); + } + + /* Last: inexact. */ + if (FE_INEXACT & excepts) + { + float x = 1.0f, y = 3.0f; + __asm__ __volatile__ ("fdivs %0, %0, %2, %1" + : "+f" (x), "+r"(tmp) : "f" (y)); + } +# endif /* __csky_fpuv2__ */ + + /* Success. */ + return 0; +} diff --git a/libm/csky/fsetexcptflg.c b/libm/csky/fsetexcptflg.c new file mode 100644 index 000000000..b6281d5c2 --- /dev/null +++ b/libm/csky/fsetexcptflg.c @@ -0,0 +1,42 @@ +/* Set floating-point environment exception handling. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "fenv_libc.h" + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fpu_control_t temp; + + /* Get the current exceptions. */ + _FPU_GETFPSR (temp); + + /* Make sure the flags we want restored are legal. */ + excepts &= FE_ALL_EXCEPT; + + /* Now clear the bits called for, and copy them in from flagp. Note that + we ignore all non-flag bits from *flagp, so they don't matter. */ + temp = ((temp >> CAUSE_SHIFT) & ~excepts) | (*flagp & excepts); + temp = temp << CAUSE_SHIFT; + + _FPU_SETFPSR (temp); + + /* Success. */ + return 0; +} diff --git a/libm/csky/ftestexcept.c b/libm/csky/ftestexcept.c new file mode 100644 index 000000000..6e3217eb1 --- /dev/null +++ b/libm/csky/ftestexcept.c @@ -0,0 +1,28 @@ +/* Test exception in current environment. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include "fenv_libc.h" +#include "fenv_private.h" +#include <stdio.h> + +int +fetestexcept (int excepts) +{ + return libc_fetestexcept_vfp (excepts); +} diff --git a/libm/e_exp.c b/libm/e_exp.c index ffa556120..f694f67d1 100644 --- a/libm/e_exp.c +++ b/libm/e_exp.c @@ -126,7 +126,7 @@ double __ieee754_exp(double x) /* default IEEE double exp */ if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; } else { - k = invln2*x+halF[xsb]; + k = (int32_t)(invln2*x+halF[xsb]); t = k; hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ lo = t*ln2LO[0]; diff --git a/libm/float_wrappers.c b/libm/float_wrappers.c index 948f6bc14..35887dde2 100644 --- a/libm/float_wrappers.c +++ b/libm/float_wrappers.c @@ -230,7 +230,7 @@ long_WRAPPER1(lround) float modff (float x, float *iptr) { double y, result; - result = modf( x, &y ); + result = modf( (double)x, &y ); *iptr = (float)y; return (float) result; } diff --git a/libm/m68k/Makefile.arch b/libm/m68k/Makefile.arch new file mode 100644 index 000000000..bd38690be --- /dev/null +++ b/libm/m68k/Makefile.arch @@ -0,0 +1,16 @@ +# Makefile for uClibc-ng +# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + +ifeq ($(UCLIBC_HAS_FENV),y) +libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c) +libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC)) +endif + +libm_ARCH_OBJS:=$(libm_ARCH_OBJ) + +ifeq ($(DOPIC),y) +libm-a-y+=$(libm_ARCH_OBJS:.o=.os) +else +libm-a-y+=$(libm_ARCH_OBJS) +endif +libm-so-y+=$(libm_ARCH_OBJS:.o=.os) diff --git a/libm/m68k/fclrexcpt.c b/libm/m68k/fclrexcpt.c new file mode 100644 index 000000000..904ba5a19 --- /dev/null +++ b/libm/m68k/fclrexcpt.c @@ -0,0 +1,39 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> + +int +feclearexcept (int excepts) +{ + fexcept_t fpsr; + + /* Mask out unsupported bits/exceptions. */ + excepts &= FE_ALL_EXCEPT; + + /* Fetch the fpu status register. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + /* Clear the relevant bits. */ + fpsr &= ~excepts; + + /* Put the new data in effect. */ + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); + + /* Success. */ + return 0; +} diff --git a/libm/m68k/fedisblxcpt.c b/libm/m68k/fedisblxcpt.c new file mode 100644 index 000000000..c2c593e38 --- /dev/null +++ b/libm/m68k/fedisblxcpt.c @@ -0,0 +1,36 @@ +/* Disable floating-point exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> + +int +fedisableexcept (int excepts) +{ + unsigned int old_exc, new_exc; + + /* Get the current control register contents. */ + __asm__ ("fmove%.l %!,%0" : "=dm" (new_exc)); + + old_exc = (new_exc >> 6) & FE_ALL_EXCEPT; + + excepts &= FE_ALL_EXCEPT; + + new_exc &= ~(excepts << 6); + __asm__ ("fmove%.l %0,%!" : : "dm" (new_exc)); + + return old_exc; +} diff --git a/libm/m68k/feenablxcpt.c b/libm/m68k/feenablxcpt.c new file mode 100644 index 000000000..9c01dc28b --- /dev/null +++ b/libm/m68k/feenablxcpt.c @@ -0,0 +1,36 @@ +/* Enable floating-point exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> + +int +feenableexcept (int excepts) +{ + unsigned int new_exc, old_exc; + + /* Get the current control register contents. */ + __asm__ ("fmove%.l %!,%0" : "=dm" (new_exc)); + + old_exc = (new_exc >> 6) & FE_ALL_EXCEPT; + + excepts &= FE_ALL_EXCEPT; + + new_exc |= excepts << 6; + __asm__ ("fmove%.l %0,%!" : : "dm" (new_exc)); + + return old_exc; +} diff --git a/libm/m68k/fegetenv.c b/libm/m68k/fegetenv.c new file mode 100644 index 000000000..2cd0a7c88 --- /dev/null +++ b/libm/m68k/fegetenv.c @@ -0,0 +1,33 @@ +/* Store current floating-point environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> + +int +fegetenv (fenv_t *envp) +{ +#ifdef __mcoldfire__ + __asm__ ("fmove%.l %/fpcr,%0" : "=dm" (envp->__control_register)); + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (envp->__status_register)); + __asm__ ("fmove%.l %/fpiar,%0" : "=dm" (envp->__instruction_address)); +#else + __asm__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (*envp)); +#endif + + /* Success. */ + return 0; +} diff --git a/libm/m68k/fegetexcept.c b/libm/m68k/fegetexcept.c new file mode 100644 index 000000000..1be3f8bf5 --- /dev/null +++ b/libm/m68k/fegetexcept.c @@ -0,0 +1,29 @@ +/* Get enabled floating-point exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> + +int +fegetexcept (void) +{ + unsigned int exc; + + /* Get the current control register contents. */ + __asm__ ("fmove%.l %!,%0" : "=dm" (exc)); + + return (exc >> 6) & FE_ALL_EXCEPT; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_barrier_wait.S b/libm/m68k/fegetmode.c index d22c72467..19f49922a 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_barrier_wait.S +++ b/libm/m68k/fegetmode.c @@ -1,6 +1,5 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. +/* Store current floating-point control modes. M68K version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -14,6 +13,14 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ -#include "../i486/pthread_barrier_wait.S" +#include <fenv.h> +#include <fpu_control.h> + +int +fegetmode (femode_t *modep) +{ + _FPU_GETCW (*modep); + return 0; +} diff --git a/libm/m68k/fegetround.c b/libm/m68k/fegetround.c new file mode 100644 index 000000000..02f6c4c41 --- /dev/null +++ b/libm/m68k/fegetround.c @@ -0,0 +1,28 @@ +/* Return current rounding direction. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> + +int +fegetround (void) +{ + int fpcr; + + __asm__ ("fmove%.l %!,%0" : "=dm" (fpcr)); + + return fpcr & FE_UPWARD; +} diff --git a/libm/m68k/feholdexcpt.c b/libm/m68k/feholdexcpt.c new file mode 100644 index 000000000..c0891969a --- /dev/null +++ b/libm/m68k/feholdexcpt.c @@ -0,0 +1,42 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> + +int +feholdexcept (fenv_t *envp) +{ + fexcept_t fpcr, fpsr; + + /* Store the environment. */ +#ifdef __mcoldfire__ + __asm__ ("fmove%.l %/fpcr,%0" : "=dm" (envp->__control_register)); + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (envp->__status_register)); + __asm__ ("fmove%.l %/fpiar,%0" : "=dm" (envp->__instruction_address)); +#else + __asm__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (*envp)); +#endif + + /* Now clear all exceptions. */ + fpsr = envp->__status_register & ~FE_ALL_EXCEPT; + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); + /* And set all exceptions to non-stop. */ + fpcr = envp->__control_register & ~(FE_ALL_EXCEPT << 6); + __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (fpcr)); + + return 0; +} diff --git a/libm/m68k/fesetenv.c b/libm/m68k/fesetenv.c new file mode 100644 index 000000000..873eb9abe --- /dev/null +++ b/libm/m68k/fesetenv.c @@ -0,0 +1,63 @@ +/* Install given floating-point environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> + +int +fesetenv (const fenv_t *envp) +{ + fenv_t temp; + + /* Install the environment specified by ENVP. But there are a few + values which we do not want to come from the saved environment. + Therefore, we get the current environment and replace the values + we want to use from the environment specified by the parameter. */ +#ifdef __mcoldfire__ + __asm__ ("fmove%.l %/fpcr,%0" : "=dm" (temp.__control_register)); + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (temp.__status_register)); + __asm__ ("fmove%.l %/fpiar,%0" : "=dm" (temp.__instruction_address)); +#else + __asm__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (*&temp)); +#endif + + temp.__status_register &= ~FE_ALL_EXCEPT; + temp.__control_register &= ~((FE_ALL_EXCEPT << 6) | FE_UPWARD); + if (envp == FE_DFL_ENV) + ; + else if (envp == FE_NOMASK_ENV) + temp.__control_register |= FE_ALL_EXCEPT << 6; + else + { + temp.__control_register |= (envp->__control_register + & ((FE_ALL_EXCEPT << 6) | FE_UPWARD)); + temp.__status_register |= envp->__status_register & FE_ALL_EXCEPT; + } + +#ifdef __mcoldfire__ + __asm__ __volatile__ ("fmove%.l %0,%/fpiar" + :: "dm" (temp.__instruction_address)); + __asm__ __volatile__ ("fmove%.l %0,%/fpcr" + :: "dm" (temp.__control_register)); + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" + :: "dm" (temp.__status_register)); +#else + __asm__ __volatile__ ("fmovem%.l %0,%/fpcr/%/fpsr/%/fpiar" : : "m" (*&temp)); +#endif + + /* Success. */ + return 0; +} diff --git a/libm/m68k/fesetexcept.c b/libm/m68k/fesetexcept.c new file mode 100644 index 000000000..6ae4a55ea --- /dev/null +++ b/libm/m68k/fesetexcept.c @@ -0,0 +1,30 @@ +/* Set given exception flags. M68K version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> + +int +fesetexcept (int excepts) +{ + fexcept_t fpsr; + + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + fpsr |= excepts & FE_ALL_EXCEPT; + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); + + return 0; +} diff --git a/libm/m68k/fesetmode.c b/libm/m68k/fesetmode.c new file mode 100644 index 000000000..a7e93d616 --- /dev/null +++ b/libm/m68k/fesetmode.c @@ -0,0 +1,31 @@ +/* Install given floating-point control modes. M68K version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetmode (const femode_t *modep) +{ + femode_t mode; + if (modep == FE_DFL_MODE) + mode = _FPU_DEFAULT; + else + mode = *modep; + _FPU_SETCW (mode); + return 0; +} diff --git a/libm/m68k/fesetround.c b/libm/m68k/fesetround.c new file mode 100644 index 000000000..a8abc4e6e --- /dev/null +++ b/libm/m68k/fesetround.c @@ -0,0 +1,35 @@ +/* Set current rounding direction. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> + +int +fesetround (int round) +{ + fexcept_t fpcr; + + if (round & ~FE_UPWARD) + /* ROUND is no valid rounding mode. */ + return 1; + + __asm__ ("fmove%.l %!,%0" : "=dm" (fpcr)); + fpcr &= ~FE_UPWARD; + fpcr |= round; + __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (fpcr)); + + return 0; +} diff --git a/libm/m68k/feupdateenv.c b/libm/m68k/feupdateenv.c new file mode 100644 index 000000000..29dcc712e --- /dev/null +++ b/libm/m68k/feupdateenv.c @@ -0,0 +1,39 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> + +int +feupdateenv (const fenv_t *envp) +{ + fexcept_t fpsr; + + /* Save current exceptions. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + fpsr &= FE_ALL_EXCEPT; + + /* Install new environment. */ + fesetenv (envp); + + /* Raise the saved exception. Incidentally for us the implementation + defined format of the values in objects of type fexcept_t is the + same as the ones specified using the FE_* constants. */ + feraiseexcept ((int) fpsr); + + /* Success. */ + return 0; +} diff --git a/libm/m68k/fgetexcptflg.c b/libm/m68k/fgetexcptflg.c new file mode 100644 index 000000000..7a564555b --- /dev/null +++ b/libm/m68k/fgetexcptflg.c @@ -0,0 +1,32 @@ +/* Store current representation for exceptions. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + fexcept_t fpsr; + + /* Get the current exceptions. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + *flagp = fpsr & excepts & FE_ALL_EXCEPT; + + /* Success. */ + return 0; +} diff --git a/libm/m68k/fraiseexcpt.c b/libm/m68k/fraiseexcpt.c new file mode 100644 index 000000000..4599c08f7 --- /dev/null +++ b/libm/m68k/fraiseexcpt.c @@ -0,0 +1,106 @@ +/* Raise given exceptions. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <float.h> +#include <math.h> + +int +feraiseexcept (int excepts) +{ +#if defined(__mcffpu__) + + /* The Coldfire FPU allows an exception to be raised by asserting + the associated EXC bit and then executing an arbitrary arithmetic + instruction. fmove.l is classified as an arithmetic instruction + and suffices for this purpose. + + We therefore raise an exception by setting both the EXC and AEXC + bit associated with the exception (the former being 6 bits to the + left of the latter) and then loading the longword at (%sp) into an + FP register. */ + + inline void + raise_one_exception (int mask) + { + if (excepts & mask) + { + int fpsr; + double unused; + + __asm__ volatile ("fmove%.l %/fpsr,%0" : "=d" (fpsr)); + fpsr |= (mask << 6) | mask; + __asm__ volatile ("fmove%.l %0,%/fpsr" :: "d" (fpsr)); + __asm__ volatile ("fmove%.l (%%sp),%0" : "=f" (unused)); + } + } + + raise_one_exception (FE_INVALID); + raise_one_exception (FE_DIVBYZERO); + raise_one_exception (FE_OVERFLOW); + raise_one_exception (FE_UNDERFLOW); + raise_one_exception (FE_INEXACT); + +#else + /* Raise exceptions represented by EXCEPTS. But we must raise only one + signal at a time. It is important that if the overflow/underflow + exception and the divide by zero exception are given at the same + time, the overflow/underflow exception follows the divide by zero + exception. */ + + /* First: invalid exception. */ + if (excepts & FE_INVALID) + { + /* One example of an invalid operation is 0 * Infinity. */ + double d = HUGE_VAL; + __asm__ __volatile__ ("fmul%.s %#0r0,%0; fnop" : "=f" (d) : "0" (d)); + } + + /* Next: division by zero. */ + if (excepts & FE_DIVBYZERO) + { + double d = 1.0; + __asm__ __volatile__ ("fdiv%.s %#0r0,%0; fnop" : "=f" (d) : "0" (d)); + } + + /* Next: overflow. */ + if (excepts & FE_OVERFLOW) + { + long double d = LDBL_MAX; + + __asm__ __volatile__ ("fmul%.x %0,%0; fnop" : "=f" (d) : "0" (d)); + } + + /* Next: underflow. */ + if (excepts & FE_UNDERFLOW) + { + long double d = -LDBL_MAX; + + __asm__ __volatile__ ("fetox%.x %0; fnop" : "=f" (d) : "0" (d)); + } + + /* Last: inexact. */ + if (excepts & FE_INEXACT) + { + long double d = 1.0; + __asm__ __volatile__ ("fdiv%.s %#0r3,%0; fnop" : "=f" (d) : "0" (d)); + } + +#endif + /* Success. */ + return 0; +} diff --git a/libm/m68k/fsetexcptflg.c b/libm/m68k/fsetexcptflg.c new file mode 100644 index 000000000..18fc1811f --- /dev/null +++ b/libm/m68k/fsetexcptflg.c @@ -0,0 +1,38 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <math.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fexcept_t fpsr; + + /* Get the current status register. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + /* Install the new exception bits in the Accrued Exception Byte. */ + fpsr &= ~(excepts & FE_ALL_EXCEPT); + fpsr |= *flagp & excepts & FE_ALL_EXCEPT; + + /* Store the new status register. */ + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); + + /* Success. */ + return 0; +} diff --git a/libm/m68k/ftestexcept.c b/libm/m68k/ftestexcept.c new file mode 100644 index 000000000..1ece1a48d --- /dev/null +++ b/libm/m68k/ftestexcept.c @@ -0,0 +1,29 @@ +/* Test exception in current environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> + +int +fetestexcept (int excepts) +{ + fexcept_t fpsr; + + /* Get current exceptions. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + return fpsr & excepts & FE_ALL_EXCEPT; +} diff --git a/libm/mips/Makefile.arch b/libm/mips/Makefile.arch new file mode 100644 index 000000000..bd38690be --- /dev/null +++ b/libm/mips/Makefile.arch @@ -0,0 +1,16 @@ +# Makefile for uClibc-ng +# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + +ifeq ($(UCLIBC_HAS_FENV),y) +libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c) +libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC)) +endif + +libm_ARCH_OBJS:=$(libm_ARCH_OBJ) + +ifeq ($(DOPIC),y) +libm-a-y+=$(libm_ARCH_OBJS:.o=.os) +else +libm-a-y+=$(libm_ARCH_OBJS) +endif +libm-so-y+=$(libm_ARCH_OBJS:.o=.os) diff --git a/libm/mips/fclrexcpt.c b/libm/mips/fclrexcpt.c new file mode 100644 index 000000000..04d48d712 --- /dev/null +++ b/libm/mips/fclrexcpt.c @@ -0,0 +1,44 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_libc.h" +#include <fpu_control.h> + +int +feclearexcept (int excepts) +{ + int cw; + + /* Mask out unsupported bits/exceptions. */ + excepts &= FE_ALL_EXCEPT; + + /* Read the complete control word. */ + _FPU_GETCW (cw); + + /* Clear exception flag bits and cause bits. If the cause bit is not + cleared, the next CTC instruction (just below) will re-generate the + exception. */ + + cw &= ~(excepts | (excepts << CAUSE_SHIFT)); + + /* Put the new data in effect. */ + _FPU_SETCW (cw); + + /* Success. */ + return 0; +} diff --git a/libm/mips/fedisblxcpt.c b/libm/mips/fedisblxcpt.c new file mode 100644 index 000000000..85cd6c518 --- /dev/null +++ b/libm/mips/fedisblxcpt.c @@ -0,0 +1,38 @@ +/* Disable floating-point exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_libc.h" +#include <fpu_control.h> + +int +fedisableexcept (int excepts) +{ + unsigned int new_exc, old_exc; + + /* Get the current control word. */ + _FPU_GETCW (new_exc); + + old_exc = (new_exc & ENABLE_MASK) >> ENABLE_SHIFT; + + excepts &= FE_ALL_EXCEPT; + + new_exc &= ~(excepts << ENABLE_SHIFT); + _FPU_SETCW (new_exc); + + return old_exc; +} diff --git a/libm/mips/feenablxcpt.c b/libm/mips/feenablxcpt.c new file mode 100644 index 000000000..9d919a8ba --- /dev/null +++ b/libm/mips/feenablxcpt.c @@ -0,0 +1,38 @@ +/* Enable floating-point exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_libc.h" +#include <fpu_control.h> + +int +feenableexcept (int excepts) +{ + unsigned int new_exc, old_exc; + + /* Get the current control word. */ + _FPU_GETCW (new_exc); + + old_exc = (new_exc & ENABLE_MASK) >> ENABLE_SHIFT; + + excepts &= FE_ALL_EXCEPT; + + new_exc |= excepts << ENABLE_SHIFT; + _FPU_SETCW (new_exc); + + return old_exc; +} diff --git a/libm/mips/fegetenv.c b/libm/mips/fegetenv.c new file mode 100644 index 000000000..94f3444ac --- /dev/null +++ b/libm/mips/fegetenv.c @@ -0,0 +1,28 @@ +/* Store current floating-point environment. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetenv (fenv_t *envp) +{ + _FPU_GETCW (*envp); + + /* Success. */ + return 0; +} diff --git a/libm/mips/fegetexcept.c b/libm/mips/fegetexcept.c new file mode 100644 index 000000000..4c7c89fa6 --- /dev/null +++ b/libm/mips/fegetexcept.c @@ -0,0 +1,31 @@ +/* Get enabled floating-point exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_libc.h" +#include <fpu_control.h> + +int +fegetexcept (void) +{ + unsigned int exc; + + /* Get the current control word. */ + _FPU_GETCW (exc); + + return (exc & ENABLE_MASK) >> ENABLE_SHIFT; +} diff --git a/libm/mips/fegetmode.c b/libm/mips/fegetmode.c new file mode 100644 index 000000000..136b8d3fb --- /dev/null +++ b/libm/mips/fegetmode.c @@ -0,0 +1,26 @@ +/* Store current floating-point control modes. MIPS version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetmode (femode_t *modep) +{ + _FPU_GETCW (*modep); + return 0; +} diff --git a/libm/mips/fegetround.c b/libm/mips/fegetround.c new file mode 100644 index 000000000..4d8f3744d --- /dev/null +++ b/libm/mips/fegetround.c @@ -0,0 +1,30 @@ +/* Return current rounding direction. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetround (void) +{ + int cw; + + /* Get control word. */ + _FPU_GETCW (cw); + + return cw & _FPU_RC_MASK; +} diff --git a/libm/mips/feholdexcpt.c b/libm/mips/feholdexcpt.c new file mode 100644 index 000000000..b1e35ae5a --- /dev/null +++ b/libm/mips/feholdexcpt.c @@ -0,0 +1,35 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feholdexcept (fenv_t *envp) +{ + fpu_control_t cw; + + /* Save the current state. */ + _FPU_GETCW (cw); + envp->__fp_control_register = cw; + + /* Clear all exception enable bits and flags. */ + cw &= ~(_FPU_MASK_V|_FPU_MASK_Z|_FPU_MASK_O|_FPU_MASK_U|_FPU_MASK_I|FE_ALL_EXCEPT); + _FPU_SETCW (cw); + + return 0; +} diff --git a/libm/mips/fenv_libc.h b/libm/mips/fenv_libc.h new file mode 100644 index 000000000..642a7b127 --- /dev/null +++ b/libm/mips/fenv_libc.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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_LIBC_H +#define _FENV_LIBC_H 1 + +/* Mask for enabling exceptions and for the CAUSE bits. */ +#define ENABLE_MASK 0x00F80U +#define CAUSE_MASK 0x1F000U + +/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits. */ +#define ENABLE_SHIFT 5 +#define CAUSE_SHIFT 10 + + +#endif /* _FENV_LIBC_H */ diff --git a/libm/mips/fenv_private.h b/libm/mips/fenv_private.h new file mode 100644 index 000000000..bc9be3b62 --- /dev/null +++ b/libm/mips/fenv_private.h @@ -0,0 +1,238 @@ +/* Internal math stuff. MIPS version. + Copyright (C) 2013-2025 Free Software Foundation, Inc. + + 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 MIPS_FENV_PRIVATE_H +#define MIPS_FENV_PRIVATE_H 1 + +/* Inline functions to speed up the math library implementation. The + default versions of these routines are in generic/fenv_private.h + and call fesetround, feholdexcept, etc. These routines use inlined + code instead. */ + +#include <fenv.h> +#include "fenv_libc.h" +#include <fpu_control.h> + +#define _FPU_MASK_ALL (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O \ + |_FPU_MASK_U | _FPU_MASK_I | FE_ALL_EXCEPT) + +static __always_inline void +libc_feholdexcept_mips (fenv_t *envp) +{ + fpu_control_t cw; + + /* Save the current state. */ + _FPU_GETCW (cw); + envp->__fp_control_register = cw; + + /* Clear all exception enable bits and flags. */ + cw &= ~(_FPU_MASK_ALL); + _FPU_SETCW (cw); +} +#define libc_feholdexcept libc_feholdexcept_mips +#define libc_feholdexceptf libc_feholdexcept_mips +#define libc_feholdexceptl libc_feholdexcept_mips + +static __always_inline void +libc_fesetround_mips (int round) +{ + fpu_control_t cw; + + /* Get current state. */ + _FPU_GETCW (cw); + + /* Set rounding bits. */ + cw &= ~_FPU_RC_MASK; + cw |= round; + + /* Set new state. */ + _FPU_SETCW (cw); +} +#define libc_fesetround libc_fesetround_mips +#define libc_fesetroundf libc_fesetround_mips +#define libc_fesetroundl libc_fesetround_mips + +static __always_inline void +libc_feholdexcept_setround_mips (fenv_t *envp, int round) +{ + fpu_control_t cw; + + /* Save the current state. */ + _FPU_GETCW (cw); + envp->__fp_control_register = cw; + + /* Clear all exception enable bits and flags. */ + cw &= ~(_FPU_MASK_ALL); + + /* Set rounding bits. */ + cw &= ~_FPU_RC_MASK; + cw |= round; + + /* Set new state. */ + _FPU_SETCW (cw); +} +#define libc_feholdexcept_setround libc_feholdexcept_setround_mips +#define libc_feholdexcept_setroundf libc_feholdexcept_setround_mips +#define libc_feholdexcept_setroundl libc_feholdexcept_setround_mips + +#define libc_feholdsetround libc_feholdexcept_setround_mips +#define libc_feholdsetroundf libc_feholdexcept_setround_mips +#define libc_feholdsetroundl libc_feholdexcept_setround_mips + +static __always_inline void +libc_fesetenv_mips (fenv_t *envp) +{ + fpu_control_t cw __attribute__ ((unused)); + + /* Read current state to flush fpu pipeline. */ + _FPU_GETCW (cw); + + _FPU_SETCW (envp->__fp_control_register); +} +#define libc_fesetenv libc_fesetenv_mips +#define libc_fesetenvf libc_fesetenv_mips +#define libc_fesetenvl libc_fesetenv_mips + +static __always_inline int +libc_feupdateenv_test_mips (fenv_t *envp, int excepts) +{ + /* int ret = fetestexcept (excepts); feupdateenv (envp); return ret; */ + int cw, temp; + + /* Get current control word. */ + _FPU_GETCW (cw); + + /* Set flag bits (which are accumulative), and *also* set the + cause bits. The setting of the cause bits is what actually causes + the hardware to generate the exception, if the corresponding enable + bit is set as well. */ + temp = cw & FE_ALL_EXCEPT; + temp |= envp->__fp_control_register | (temp << CAUSE_SHIFT); + + /* Set new state. */ + _FPU_SETCW (temp); + + return cw & excepts & FE_ALL_EXCEPT; +} +#define libc_feupdateenv_test libc_feupdateenv_test_mips +#define libc_feupdateenv_testf libc_feupdateenv_test_mips +#define libc_feupdateenv_testl libc_feupdateenv_test_mips + +static __always_inline void +libc_feupdateenv_mips (fenv_t *envp) +{ + libc_feupdateenv_test_mips (envp, 0); +} +#define libc_feupdateenv libc_feupdateenv_mips +#define libc_feupdateenvf libc_feupdateenv_mips +#define libc_feupdateenvl libc_feupdateenv_mips + +#define libc_feresetround libc_feupdateenv_mips +#define libc_feresetroundf libc_feupdateenv_mips +#define libc_feresetroundl libc_feupdateenv_mips + +static __always_inline int +libc_fetestexcept_mips (int excepts) +{ + int cw; + + /* Get current control word. */ + _FPU_GETCW (cw); + + return cw & excepts & FE_ALL_EXCEPT; +} +#define libc_fetestexcept libc_fetestexcept_mips +#define libc_fetestexceptf libc_fetestexcept_mips +#define libc_fetestexceptl libc_fetestexcept_mips + +/* Enable support for rounding mode context. */ +#define HAVE_RM_CTX 1 + +static __always_inline void +libc_feholdexcept_setround_mips_ctx (struct rm_ctx *ctx, int round) +{ + fpu_control_t old, new; + + /* Save the current state. */ + _FPU_GETCW (old); + ctx->env.__fp_control_register = old; + + /* Clear all exception enable bits and flags. */ + new = old & ~(_FPU_MASK_ALL); + + /* Set rounding bits. */ + new = (new & ~_FPU_RC_MASK) | round; + + if (__glibc_unlikely (new != old)) + { + _FPU_SETCW (new); + ctx->updated_status = true; + } + else + ctx->updated_status = false; +} +#define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_mips_ctx +#define libc_feholdexcept_setroundf_ctx libc_feholdexcept_setround_mips_ctx +#define libc_feholdexcept_setroundl_ctx libc_feholdexcept_setround_mips_ctx + +static __always_inline void +libc_fesetenv_mips_ctx (struct rm_ctx *ctx) +{ + libc_fesetenv_mips (&ctx->env); +} +#define libc_fesetenv_ctx libc_fesetenv_mips_ctx +#define libc_fesetenvf_ctx libc_fesetenv_mips_ctx +#define libc_fesetenvl_ctx libc_fesetenv_mips_ctx + +static __always_inline void +libc_feupdateenv_mips_ctx (struct rm_ctx *ctx) +{ + if (__glibc_unlikely (ctx->updated_status)) + libc_feupdateenv_test_mips (&ctx->env, 0); +} +#define libc_feupdateenv_ctx libc_feupdateenv_mips_ctx +#define libc_feupdateenvf_ctx libc_feupdateenv_mips_ctx +#define libc_feupdateenvl_ctx libc_feupdateenv_mips_ctx +#define libc_feresetround_ctx libc_feupdateenv_mips_ctx +#define libc_feresetroundf_ctx libc_feupdateenv_mips_ctx +#define libc_feresetroundl_ctx libc_feupdateenv_mips_ctx + +static __always_inline void +libc_feholdsetround_mips_ctx (struct rm_ctx *ctx, int round) +{ + fpu_control_t old, new; + + /* Save the current state. */ + _FPU_GETCW (old); + ctx->env.__fp_control_register = old; + + /* Set rounding bits. */ + new = (old & ~_FPU_RC_MASK) | round; + + if (__glibc_unlikely (new != old)) + { + _FPU_SETCW (new); + ctx->updated_status = true; + } + else + ctx->updated_status = false; +} +#define libc_feholdsetround_ctx libc_feholdsetround_mips_ctx +#define libc_feholdsetroundf_ctx libc_feholdsetround_mips_ctx +#define libc_feholdsetroundl_ctx libc_feholdsetround_mips_ctx + +#endif diff --git a/libm/mips/fesetenv.c b/libm/mips/fesetenv.c new file mode 100644 index 000000000..03b5b91a6 --- /dev/null +++ b/libm/mips/fesetenv.c @@ -0,0 +1,38 @@ +/* Install given floating-point environment. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetenv (const fenv_t *envp) +{ + fpu_control_t cw; + + /* Read first current state to flush fpu pipeline. */ + _FPU_GETCW (cw); + + if (envp == FE_DFL_ENV) + _FPU_SETCW (_FPU_DEFAULT); + else if (envp == FE_NOMASK_ENV) + _FPU_SETCW (_FPU_IEEE); + else + _FPU_SETCW (envp->__fp_control_register); + + /* Success. */ + return 0; +} diff --git a/libm/mips/fesetexcept.c b/libm/mips/fesetexcept.c new file mode 100644 index 000000000..1c9a0de3b --- /dev/null +++ b/libm/mips/fesetexcept.c @@ -0,0 +1,31 @@ +/* Set given exception flags. MIPS version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetexcept (int excepts) +{ + fpu_control_t temp; + + _FPU_GETCW (temp); + temp |= excepts & FE_ALL_EXCEPT; + _FPU_SETCW (temp); + + return 0; +} diff --git a/libm/mips/fesetmode.c b/libm/mips/fesetmode.c new file mode 100644 index 000000000..cb4ffdc06 --- /dev/null +++ b/libm/mips/fesetmode.c @@ -0,0 +1,37 @@ +/* Install given floating-point control modes. MIPS version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +#define FCSR_STATUS 0xfe83f07c + +int +fesetmode (const femode_t *modep) +{ + fpu_control_t cw; + + _FPU_GETCW (cw); + cw &= FCSR_STATUS; + if (modep == FE_DFL_MODE) + cw |= _FPU_DEFAULT; + else + cw |= *modep & ~FCSR_STATUS; + _FPU_SETCW (cw); + + return 0; +} diff --git a/libm/mips/fesetround.c b/libm/mips/fesetround.c new file mode 100644 index 000000000..532092710 --- /dev/null +++ b/libm/mips/fesetround.c @@ -0,0 +1,40 @@ +/* Set current rounding direction. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetround (int round) +{ + fpu_control_t cw; + + if ((round & ~_FPU_RC_MASK) != 0) + /* ROUND is no valid rounding mode. */ + return 1; + + /* Get current state. */ + _FPU_GETCW (cw); + + /* Set rounding bits. */ + cw &= ~_FPU_RC_MASK; + cw |= round; + /* Set new state. */ + _FPU_SETCW (cw); + + return 0; +} diff --git a/libm/mips/feupdateenv.c b/libm/mips/feupdateenv.c new file mode 100644 index 000000000..d90604db3 --- /dev/null +++ b/libm/mips/feupdateenv.c @@ -0,0 +1,40 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feupdateenv (const fenv_t *envp) +{ + int temp; + + /* Save current exceptions. */ + _FPU_GETCW (temp); + temp &= FE_ALL_EXCEPT; + + /* Install new environment. */ + fesetenv (envp); + + /* Raise the saved exception. Incidentally for us the implementation + defined format of the values in objects of type fexcept_t is the + same as the ones specified using the FE_* constants. */ + feraiseexcept (temp); + + /* Success. */ + return 0; +} diff --git a/libm/mips/fgetexcptflg.c b/libm/mips/fgetexcptflg.c new file mode 100644 index 000000000..b03eca55e --- /dev/null +++ b/libm/mips/fgetexcptflg.c @@ -0,0 +1,37 @@ +/* Store current representation for exceptions. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + fpu_control_t temp; + + /* Get the current exceptions. */ + _FPU_GETCW (temp); + + /* We only save the relevant bits here. In particular, care has to be + taken with the CAUSE bits, as an inadvertent restore later on could + generate unexpected exceptions. */ + + *flagp = temp & excepts & FE_ALL_EXCEPT; + + /* Success. */ + return 0; +} diff --git a/libm/mips/fraiseexcpt.c b/libm/mips/fraiseexcpt.c new file mode 100644 index 000000000..6327b1104 --- /dev/null +++ b/libm/mips/fraiseexcpt.c @@ -0,0 +1,42 @@ +/* Raise given exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_libc.h" +#include <fpu_control.h> + +int +feraiseexcept (int excepts) +{ + fpu_control_t cw; + + /* Get current state. */ + _FPU_GETCW (cw); + + /* Set flag bits (which are accumulative), and *also* set the + cause bits. The setting of the cause bits is what actually causes + the hardware to generate the exception, if the corresponding enable + bit is set as well. */ + + excepts &= FE_ALL_EXCEPT; + cw |= excepts | (excepts << CAUSE_SHIFT); + + /* Set new state. */ + _FPU_SETCW (cw); + + return 0; +} diff --git a/libm/mips/fsetexcptflg.c b/libm/mips/fsetexcptflg.c new file mode 100644 index 000000000..d98a300e2 --- /dev/null +++ b/libm/mips/fsetexcptflg.c @@ -0,0 +1,40 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fpu_control_t temp; + + /* Get the current exceptions. */ + _FPU_GETCW (temp); + + /* Make sure the flags we want restored are legal. */ + excepts &= FE_ALL_EXCEPT; + + /* Now clear the bits called for, and copy them in from flagp. Note that + we ignore all non-flag bits from *flagp, so they don't matter. */ + temp = (temp & ~excepts) | (*flagp & excepts); + + _FPU_SETCW (temp); + + /* Success. */ + return 0; +} diff --git a/libm/mips/ftestexcept.c b/libm/mips/ftestexcept.c new file mode 100644 index 000000000..8fdca7560 --- /dev/null +++ b/libm/mips/ftestexcept.c @@ -0,0 +1,30 @@ +/* Test exception in current environment. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fetestexcept (int excepts) +{ + int cw; + + /* Get current control word. */ + _FPU_GETCW (cw); + + return cw & excepts & FE_ALL_EXCEPT; +} diff --git a/libm/nan.c b/libm/nan.c index 454734b6f..9c2cd6e90 100644 --- a/libm/nan.c +++ b/libm/nan.c @@ -28,7 +28,7 @@ double nan (const char *tagp) sprintf (buf, "NAN(%s)", tagp); return strtod (buf, NULL); } - return NAN; + return (double)NAN; } libm_hidden_def(nan) @@ -53,7 +53,7 @@ long double nanl (const char *tagp) sprintf (buf, "NAN(%s)", tagp); return strtold (buf, NULL); } - return NAN; + return (long double)NAN; } libm_hidden_def(nanl) #endif diff --git a/libm/or1k/Makefile.arch b/libm/or1k/Makefile.arch new file mode 100644 index 000000000..bd38690be --- /dev/null +++ b/libm/or1k/Makefile.arch @@ -0,0 +1,16 @@ +# Makefile for uClibc-ng +# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + +ifeq ($(UCLIBC_HAS_FENV),y) +libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c) +libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC)) +endif + +libm_ARCH_OBJS:=$(libm_ARCH_OBJ) + +ifeq ($(DOPIC),y) +libm-a-y+=$(libm_ARCH_OBJS:.o=.os) +else +libm-a-y+=$(libm_ARCH_OBJS) +endif +libm-so-y+=$(libm_ARCH_OBJS:.o=.os) diff --git a/libm/or1k/fclrexcpt.c b/libm/or1k/fclrexcpt.c new file mode 100644 index 000000000..ecb327d72 --- /dev/null +++ b/libm/or1k/fclrexcpt.c @@ -0,0 +1,42 @@ +/* Clear given exceptions in current floating-point environment. + OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feclearexcept (int excepts) +{ + fpu_control_t cw; + fpu_control_t cw_new; + + /* Mask out unsupported bits/exceptions. */ + excepts &= FE_ALL_EXCEPT; + + /* Read the complete control word. */ + _FPU_GETCW (cw); + + cw_new = cw & ~excepts; + + /* Put the new data in effect. */ + if (cw != cw_new) + _FPU_SETCW (cw_new); + + /* Success. */ + return 0; +} diff --git a/libm/or1k/fegetenv.c b/libm/or1k/fegetenv.c new file mode 100644 index 000000000..7769d456f --- /dev/null +++ b/libm/or1k/fegetenv.c @@ -0,0 +1,28 @@ +/* Store current floating-point environment. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetenv (fenv_t *envp) +{ + _FPU_GETCW (*envp); + + /* Success. */ + return 0; +} diff --git a/libm/or1k/fegetmode.c b/libm/or1k/fegetmode.c new file mode 100644 index 000000000..40a789329 --- /dev/null +++ b/libm/or1k/fegetmode.c @@ -0,0 +1,28 @@ +/* Store current floating-point control modes. OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetmode (femode_t *modep) +{ + _FPU_GETCW (*modep); + + /* Success. */ + return 0; +} diff --git a/libm/or1k/fegetround.c b/libm/or1k/fegetround.c new file mode 100644 index 000000000..0965de2f9 --- /dev/null +++ b/libm/or1k/fegetround.c @@ -0,0 +1,25 @@ +/* Return current rounding direction. OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include "get-rounding-mode.h" + +int +fegetround (void) +{ + return get_rounding_mode (); +} diff --git a/libm/or1k/feholdexcpt.c b/libm/or1k/feholdexcpt.c new file mode 100644 index 000000000..cff06f3d0 --- /dev/null +++ b/libm/or1k/feholdexcpt.c @@ -0,0 +1,29 @@ +/* Store current floating-point environment and clear exceptions. + OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +feholdexcept (fenv_t *envp) +{ + libc_feholdexcept_or1k (envp); + + /* Success. */ + return 0; +} diff --git a/libm/or1k/fenv_private.h b/libm/or1k/fenv_private.h new file mode 100644 index 000000000..ede7d243a --- /dev/null +++ b/libm/or1k/fenv_private.h @@ -0,0 +1,196 @@ +/* Private floating point rounding and exceptions handling. OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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 OR1K_FENV_PRIVATE_H +#define OR1K_FENV_PRIVATE_H 1 + +#include <fenv.h> +#include <fpu_control.h> + +static __always_inline void +libc_feholdexcept_or1k (fenv_t *envp) +{ + fpu_control_t cw; + fpu_control_t cw_new; + + /* Get and store the environment. */ + _FPU_GETCW (cw); + *envp = cw; + + /* Clear the exception status flags. */ + cw_new = cw & ~FE_ALL_EXCEPT; + + if (cw != cw_new) + _FPU_SETCW (cw_new); +} + +#define libc_feholdexcept libc_feholdexcept_or1k +#define libc_feholdexceptf libc_feholdexcept_or1k +#define libc_feholdexceptl libc_feholdexcept_or1k + +static __always_inline void +libc_fesetround_or1k (int round) +{ + fpu_control_t cw; + fpu_control_t cw_new; + + _FPU_GETCW (cw); + cw_new = cw & ~_FPU_FPCSR_RM_MASK; + cw_new |= round; + if (cw != cw_new) + _FPU_SETCW (cw_new); +} + +#define libc_fesetround libc_fesetround_or1k +#define libc_fesetroundf libc_fesetround_or1k +#define libc_fesetroundl libc_fesetround_or1k + +static __always_inline void +libc_feholdexcept_setround_or1k (fenv_t *envp, int round) +{ + fpu_control_t cw; + fpu_control_t cw_new; + + /* Get and store the environment. */ + _FPU_GETCW (cw); + *envp = cw; + + /* Clear the status flags and rounding mode. */ + cw_new = cw & ~(FE_ALL_EXCEPT | _FPU_FPCSR_RM_MASK); + + /* Set rounding mode. */ + cw_new |= round; + + if (cw != cw_new) + _FPU_SETCW (cw_new); +} + +#define libc_feholdexcept_setround libc_feholdexcept_setround_or1k +#define libc_feholdexcept_setroundf libc_feholdexcept_setround_or1k +#define libc_feholdexcept_setroundl libc_feholdexcept_setround_or1k + +static __always_inline int +libc_fetestexcept_or1k (int ex) +{ + fpu_control_t cw; + + /* Get current control word. */ + _FPU_GETCW (cw); + + /* Check if any of the queried exception flags are set. */ + return cw & ex & FE_ALL_EXCEPT; +} + +#define libc_fetestexcept libc_fetestexcept_or1k +#define libc_fetestexceptf libc_fetestexcept_or1k +#define libc_fetestexceptl libc_fetestexcept_or1k + +static __always_inline void +libc_fesetenv_or1k (const fenv_t *envp) +{ + if (envp == FE_DFL_ENV) + _FPU_SETCW (_FPU_DEFAULT); + else + _FPU_SETCW (*envp); +} + +#define libc_fesetenv libc_fesetenv_or1k +#define libc_fesetenvf libc_fesetenv_or1k +#define libc_fesetenvl libc_fesetenv_or1k +#define libc_feresetround_noex libc_fesetenv_or1k +#define libc_feresetround_noexf libc_fesetenv_or1k +#define libc_feresetround_noexl libc_fesetenv_or1k + +static __always_inline int +libc_feupdateenv_test_or1k (const fenv_t *envp, int ex) +{ + fpu_control_t cw; + fpu_control_t cw_new; + int excepts; + + /* Get current control word. */ + _FPU_GETCW (cw); + + /* Merge current exception flags with the passed fenv. */ + excepts = cw & FE_ALL_EXCEPT; + cw_new = (envp == FE_DFL_ENV ? _FPU_DEFAULT : *envp) | excepts; + + if (unlikely (cw != cw_new)) + _FPU_SETCW (cw_new); + + /* Raise the exceptions if enabled in the new FP state. */ + if (unlikely (excepts)) + feraiseexcept (excepts); + + return excepts & ex; +} + +#define libc_feupdateenv_test libc_feupdateenv_test_or1k +#define libc_feupdateenv_testf libc_feupdateenv_test_or1k +#define libc_feupdateenv_testl libc_feupdateenv_test_or1k + +static __always_inline void +libc_feupdateenv_or1k (const fenv_t *envp) +{ + libc_feupdateenv_test_or1k (envp, 0); +} + +#define libc_feupdateenv libc_feupdateenv_or1k +#define libc_feupdateenvf libc_feupdateenv_or1k +#define libc_feupdateenvl libc_feupdateenv_or1k + +static __always_inline void +libc_feholdsetround_or1k (fenv_t *envp, int round) +{ + fpu_control_t cw; + + _FPU_GETCW (cw); + *envp = cw; + + /* Check whether rounding modes are different. */ + round = (cw ^ round) & _FPU_FPCSR_RM_MASK; + + /* Set new rounding mode if different. */ + if (unlikely (round != 0)) + _FPU_SETCW (cw ^ round); +} + +#define libc_feholdsetround libc_feholdsetround_or1k +#define libc_feholdsetroundf libc_feholdsetround_or1k +#define libc_feholdsetroundl libc_feholdsetround_or1k + +static __always_inline void +libc_feresetround_or1k (fenv_t *envp) +{ + fpu_control_t cw; + int round; + + _FPU_GETCW (cw); + + /* Check whether rounding modes are different. */ + round = (*envp ^ cw) & _FPU_FPCSR_RM_MASK; + + /* Restore the rounding mode if it was changed. */ + if (unlikely (round != 0)) + _FPU_SETCW (cw ^ round); +} + +#define libc_feresetround libc_feresetround_or1k +#define libc_feresetroundf libc_feresetround_or1k +#define libc_feresetroundl libc_feresetround_or1k + +#endif diff --git a/libm/or1k/fesetenv.c b/libm/or1k/fesetenv.c new file mode 100644 index 000000000..a9c8448f4 --- /dev/null +++ b/libm/or1k/fesetenv.c @@ -0,0 +1,28 @@ +/* Install given floating-point environment. OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fesetenv (const fenv_t *envp) +{ + libc_fesetenv_or1k (envp); + + /* Success. */ + return 0; +} diff --git a/libm/or1k/fesetexcept.c b/libm/or1k/fesetexcept.c new file mode 100644 index 000000000..abc5624c3 --- /dev/null +++ b/libm/or1k/fesetexcept.c @@ -0,0 +1,34 @@ +/* Set given exception flags. OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetexcept (int excepts) +{ + fpu_control_t cw; + fpu_control_t cw_new; + + _FPU_GETCW (cw); + cw_new = cw | (excepts & FE_ALL_EXCEPT); + if (cw != cw_new) + _FPU_SETCW (cw_new); + + /* Success. */ + return 0; +} diff --git a/libm/or1k/fesetmode.c b/libm/or1k/fesetmode.c new file mode 100644 index 000000000..74490621b --- /dev/null +++ b/libm/or1k/fesetmode.c @@ -0,0 +1,38 @@ +/* Install given floating-point control modes. OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetmode (const femode_t *modep) +{ + fpu_control_t cw; + fpu_control_t cw_new; + + _FPU_GETCW (cw); + cw_new = cw & ~_FPU_FPCSR_RM_MASK; + if (modep == FE_DFL_MODE) + cw_new |= (_FPU_DEFAULT & _FPU_FPCSR_RM_MASK); + else + cw_new |= (*modep & _FPU_FPCSR_RM_MASK); + if (cw != cw_new) + _FPU_SETCW (cw_new); + + /* Success. */ + return 0; +} diff --git a/libm/or1k/fesetround.c b/libm/or1k/fesetround.c new file mode 100644 index 000000000..37c2db4ab --- /dev/null +++ b/libm/or1k/fesetround.c @@ -0,0 +1,35 @@ +/* Set current rounding direction. OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fesetround (int round) +{ + switch (round) + { + case FE_TONEAREST: + case FE_TOWARDZERO: + case FE_DOWNWARD: + case FE_UPWARD: + libc_fesetround_or1k (round); + return 0; + default: + return round; /* A nonzero value. */ + } +} diff --git a/libm/or1k/feupdateenv.c b/libm/or1k/feupdateenv.c new file mode 100644 index 000000000..b0f42744f --- /dev/null +++ b/libm/or1k/feupdateenv.c @@ -0,0 +1,29 @@ +/* Install given floating-point environment and raise exceptions. + OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +feupdateenv (const fenv_t *envp) +{ + libc_feupdateenv_or1k (envp); + + /* Success. */ + return 0; +} diff --git a/libm/or1k/fgetexcptflg.c b/libm/or1k/fgetexcptflg.c new file mode 100644 index 000000000..2a725a4c7 --- /dev/null +++ b/libm/or1k/fgetexcptflg.c @@ -0,0 +1,28 @@ +/* Store current state of exceptions. OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + *flagp = libc_fetestexcept_or1k (excepts); + + /* Success. */ + return 0; +} diff --git a/libm/or1k/fraiseexcpt.c b/libm/or1k/fraiseexcpt.c new file mode 100644 index 000000000..31ceb830d --- /dev/null +++ b/libm/or1k/fraiseexcpt.c @@ -0,0 +1,63 @@ +/* Raise given exceptions. OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> +#include <float.h> +#include <math.h> + +int +feraiseexcept (int excepts) +{ + if (excepts == 0) + return 0; + + /* Raise exceptions represented by EXPECTS. */ + + if (excepts & FE_INEXACT) + { + float d = 1.0, x = 3.0; + __asm__ volatile ("lf.div.s %0, %0, %1" : "+r" (d) : "r" (x)); + } + + if (excepts & FE_UNDERFLOW) + { + float d = FLT_MIN; + __asm__ volatile ("lf.mul.s %0, %0, %0" : "+r" (d)); + } + + if (excepts & FE_OVERFLOW) + { + float d = FLT_MAX; + __asm__ volatile ("lf.mul.s %0, %0, %0" : "+r" (d) : "r" (d)); + } + + if (excepts & FE_DIVBYZERO) + { + float d = 1.0, x = 0.0; + __asm__ volatile ("lf.div.s %0, %0, %1" : "+r" (d) : "r" (x)); + } + + if (excepts & FE_INVALID) + { + float d = HUGE_VAL, x = 0.0; + __asm__ volatile ("lf.mul.s %0, %1, %0" : "+r" (d) : "r" (x)); + } + + /* Success. */ + return 0; +} diff --git a/libm/or1k/fsetexcptflg.c b/libm/or1k/fsetexcptflg.c new file mode 100644 index 000000000..01c6e8635 --- /dev/null +++ b/libm/or1k/fsetexcptflg.c @@ -0,0 +1,42 @@ +/* Set floating-point environment exception handling. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fpu_control_t cw; + fpu_control_t cw_new; + + /* Get the current exceptions. */ + _FPU_GETCW (cw); + + /* Make sure the flags we want restored are legal. */ + excepts &= FE_ALL_EXCEPT; + + /* Now set selected bits from flagp. Note that we ignore all non-flag + bits from *flagp, so they don't matter. */ + cw_new = (cw & ~excepts) | (*flagp & excepts); + + if (cw != cw_new) + _FPU_SETCW (cw_new); + + /* Success. */ + return 0; +} diff --git a/libm/or1k/ftestexcept.c b/libm/or1k/ftestexcept.c new file mode 100644 index 000000000..02ddf12c8 --- /dev/null +++ b/libm/or1k/ftestexcept.c @@ -0,0 +1,25 @@ +/* Test exception in current environment. OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fetestexcept (int excepts) +{ + return libc_fetestexcept_or1k (excepts); +} diff --git a/libm/or1k/get-rounding-mode.h b/libm/or1k/get-rounding-mode.h new file mode 100644 index 000000000..f65c4ecc0 --- /dev/null +++ b/libm/or1k/get-rounding-mode.h @@ -0,0 +1,36 @@ +/* Determine floating-point rounding mode within libc. OpenRISC version. + + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + 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 _OR1K_GET_ROUNDING_MODE_H +#define _OR1K_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 cw; + + _FPU_GETCW (cw); + return cw & _FPU_FPCSR_RM_MASK; +} + +#endif /* get-rounding-mode.h */ diff --git a/libm/riscv32/Makefile.arch b/libm/riscv32/Makefile.arch new file mode 100644 index 000000000..bd38690be --- /dev/null +++ b/libm/riscv32/Makefile.arch @@ -0,0 +1,16 @@ +# Makefile for uClibc-ng +# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + +ifeq ($(UCLIBC_HAS_FENV),y) +libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c) +libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC)) +endif + +libm_ARCH_OBJS:=$(libm_ARCH_OBJ) + +ifeq ($(DOPIC),y) +libm-a-y+=$(libm_ARCH_OBJS:.o=.os) +else +libm-a-y+=$(libm_ARCH_OBJS) +endif +libm-so-y+=$(libm_ARCH_OBJS:.o=.os) diff --git a/libm/riscv32/fclrexcpt.c b/libm/riscv32/fclrexcpt.c new file mode 100644 index 000000000..849a910fc --- /dev/null +++ b/libm/riscv32/fclrexcpt.c @@ -0,0 +1,26 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feclearexcept (int excepts) +{ + __asm__ volatile ("csrc fflags, %0" : : "r" (excepts)); + return 0; +} diff --git a/libm/riscv32/fegetenv.c b/libm/riscv32/fegetenv.c new file mode 100644 index 000000000..94f3444ac --- /dev/null +++ b/libm/riscv32/fegetenv.c @@ -0,0 +1,28 @@ +/* Store current floating-point environment. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetenv (fenv_t *envp) +{ + _FPU_GETCW (*envp); + + /* Success. */ + return 0; +} diff --git a/libm/riscv32/fegetmode.c b/libm/riscv32/fegetmode.c new file mode 100644 index 000000000..4b0ff270c --- /dev/null +++ b/libm/riscv32/fegetmode.c @@ -0,0 +1,26 @@ +/* Store current floating-point control modes. RISC-V version. + Copyright (C) 2017-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetmode (femode_t *modep) +{ + _FPU_GETCW (*modep); + return 0; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_post.S b/libm/riscv32/fegetround.c index 5e7a41926..abd13fc7f 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_post.S +++ b/libm/riscv32/fegetround.c @@ -1,6 +1,5 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. +/* Return current rounding direction. + Copyright (C) 1998-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -13,7 +12,14 @@ 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 - <http://www.gnu.org/licenses/>. */ + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ -#include "../i486/sem_post.S" +#include <fenv.h> +#include "fenv_private.h" + +int +fegetround (void) +{ + return riscv_getround (); +} diff --git a/libm/riscv32/feholdexcpt.c b/libm/riscv32/feholdexcpt.c new file mode 100644 index 000000000..5d95a08fe --- /dev/null +++ b/libm/riscv32/feholdexcpt.c @@ -0,0 +1,26 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +feholdexcept (fenv_t *envp) +{ + libc_feholdexcept_riscv (envp); + return 0; +} diff --git a/libm/riscv32/fenv_private.h b/libm/riscv32/fenv_private.h new file mode 100644 index 000000000..9eed4b614 --- /dev/null +++ b/libm/riscv32/fenv_private.h @@ -0,0 +1,156 @@ +/* Private floating point rounding and exceptions handling. RISC-V version. + Copyright (C) 2014-2025 Free Software Foundation, Inc. + + 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 RISCV_FENV_PRIVATE_H +#define RISCV_FENV_PRIVATE_H 1 + +#include <fenv.h> +#include <fpu_control.h> +#include "get-rounding-mode.h" + +static __always_inline int +riscv_getround (void) +{ + return get_rounding_mode (); +} + +static __always_inline void +riscv_setround (int rm) +{ + __asm__ volatile ("fsrm %z0" : : "rJ" (rm)); +} + +static __always_inline int +riscv_getflags (void) +{ + int flags; + __asm__ volatile ("frflags %0" : "=r" (flags)); + return flags; +} + +static __always_inline void +riscv_setflags (int flags) +{ + __asm__ volatile ("fsflags %z0" : : "rJ" (flags)); +} + +static __always_inline void +libc_feholdexcept_riscv (fenv_t *envp) +{ + __asm__ volatile ("csrrc %0, fcsr, %1" : "=r" (*envp) : "i" (FE_ALL_EXCEPT)); +} + +#define libc_feholdexcept libc_feholdexcept_riscv +#define libc_feholdexceptf libc_feholdexcept_riscv +#define libc_feholdexceptl libc_feholdexcept_riscv + +static __always_inline void +libc_fesetround_riscv (int round) +{ + riscv_setround (round); +} + +#define libc_fesetround libc_fesetround_riscv +#define libc_fesetroundf libc_fesetround_riscv +#define libc_fesetroundl libc_fesetround_riscv + +static __always_inline void +libc_feholdexcept_setround_riscv (fenv_t *envp, int round) +{ + libc_feholdexcept_riscv (envp); + libc_fesetround_riscv (round); +} + +#define libc_feholdexcept_setround libc_feholdexcept_setround_riscv +#define libc_feholdexcept_setroundf libc_feholdexcept_setround_riscv +#define libc_feholdexcept_setroundl libc_feholdexcept_setround_riscv + +static __always_inline int +libc_fetestexcept_riscv (int ex) +{ + return riscv_getflags () & ex; +} + +#define libc_fetestexcept libc_fetestexcept_riscv +#define libc_fetestexceptf libc_fetestexcept_riscv +#define libc_fetestexceptl libc_fetestexcept_riscv + +static __always_inline void +libc_fesetenv_riscv (const fenv_t *envp) +{ + long int env = (envp != FE_DFL_ENV ? *envp : 0); + _FPU_SETCW (env); +} + +#define libc_fesetenv libc_fesetenv_riscv +#define libc_fesetenvf libc_fesetenv_riscv +#define libc_fesetenvl libc_fesetenv_riscv +#define libc_feresetround_noex libc_fesetenv_riscv +#define libc_feresetround_noexf libc_fesetenv_riscv +#define libc_feresetround_noexl libc_fesetenv_riscv + +static __always_inline int +libc_feupdateenv_test_riscv (const fenv_t *envp, int ex) +{ + fenv_t env = *envp; + int flags = riscv_getflags (); + __asm__ volatile ("csrw fcsr, %z0" : : "rJ" (env | flags)); + return flags & ex; +} + +#define libc_feupdateenv_test libc_feupdateenv_test_riscv +#define libc_feupdateenv_testf libc_feupdateenv_test_riscv +#define libc_feupdateenv_testl libc_feupdateenv_test_riscv + +static __always_inline void +libc_feupdateenv_riscv (const fenv_t *envp) +{ + long int env = (envp != FE_DFL_ENV ? *envp : 0); + _FPU_SETCW (env | riscv_getflags ()); +} + +#define libc_feupdateenv libc_feupdateenv_riscv +#define libc_feupdateenvf libc_feupdateenv_riscv +#define libc_feupdateenvl libc_feupdateenv_riscv + +static __always_inline void +libc_feholdsetround_riscv (fenv_t *envp, int round) +{ + /* Note this implementation makes an improperly-formatted fenv_t and + so should only be used in conjunction with libc_feresetround. */ + int old_round; + __asm__ volatile ("csrrw %0, frm, %z1" : "=r" (old_round) : "rJ" (round)); + *envp = old_round; +} + +#define libc_feholdsetround libc_feholdsetround_riscv +#define libc_feholdsetroundf libc_feholdsetround_riscv +#define libc_feholdsetroundl libc_feholdsetround_riscv + +static __always_inline void +libc_feresetround_riscv (fenv_t *envp) +{ + /* Note this implementation takes an improperly-formatted fenv_t and + so should only be used in conjunction with libc_feholdsetround. */ + riscv_setround (*envp); +} + +#define libc_feresetround libc_feresetround_riscv +#define libc_feresetroundf libc_feresetround_riscv +#define libc_feresetroundl libc_feresetround_riscv + +#endif diff --git a/libm/riscv32/fesetenv.c b/libm/riscv32/fesetenv.c new file mode 100644 index 000000000..8b7427c18 --- /dev/null +++ b/libm/riscv32/fesetenv.c @@ -0,0 +1,26 @@ +/* Install given floating-point environment. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fesetenv (const fenv_t *envp) +{ + libc_fesetenv_riscv (envp); + return 0; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S b/libm/riscv32/fesetexcept.c index 74dda472f..9c931a1b7 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S +++ b/libm/riscv32/fesetexcept.c @@ -1,6 +1,5 @@ -/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. +/* Set given exception flags. RISC-V version. + Copyright (C) 2017-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -14,6 +13,13 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ -#include "lowlevellock.S" +#include <fenv.h> + +int +fesetexcept (int excepts) +{ + __asm__ volatile ("csrs fflags, %0" : : "r" (excepts)); + return 0; +} diff --git a/libm/riscv32/fesetmode.c b/libm/riscv32/fesetmode.c new file mode 100644 index 000000000..aaaf4480b --- /dev/null +++ b/libm/riscv32/fesetmode.c @@ -0,0 +1,30 @@ +/* Install given floating-point control modes. RISC-V version. + Copyright (C) 2017-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetmode (const femode_t *modep) +{ + __asm__ volatile ("csrc fcsr, %0" : : "r" (~FE_ALL_EXCEPT)); + + if (modep != FE_DFL_MODE) + __asm__ volatile ("csrs fcsr, %0" : : "r" (*modep & ~FE_ALL_EXCEPT)); + + return 0; +} diff --git a/libm/riscv32/fesetround.c b/libm/riscv32/fesetround.c new file mode 100644 index 000000000..a791751d1 --- /dev/null +++ b/libm/riscv32/fesetround.c @@ -0,0 +1,35 @@ +/* Set current rounding direction. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fesetround (int round) +{ + switch (round) + { + case FE_TONEAREST: + case FE_TOWARDZERO: + case FE_DOWNWARD: + case FE_UPWARD: + riscv_setround (round); + return 0; + default: + return round; /* A nonzero value. */ + } +} diff --git a/libm/riscv32/feupdateenv.c b/libm/riscv32/feupdateenv.c new file mode 100644 index 000000000..ea62bd1aa --- /dev/null +++ b/libm/riscv32/feupdateenv.c @@ -0,0 +1,26 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +feupdateenv (const fenv_t *envp) +{ + libc_feupdateenv_riscv (envp); + return 0; +} diff --git a/libm/riscv32/fgetexcptflg.c b/libm/riscv32/fgetexcptflg.c new file mode 100644 index 000000000..ecf513bed --- /dev/null +++ b/libm/riscv32/fgetexcptflg.c @@ -0,0 +1,29 @@ +/* Store current representation for exceptions. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + /* Get the current exceptions. */ + *flagp = riscv_getflags () & excepts; + + /* Success. */ + return 0; +} diff --git a/libm/riscv32/fraiseexcpt.c b/libm/riscv32/fraiseexcpt.c new file mode 100644 index 000000000..f89f983d7 --- /dev/null +++ b/libm/riscv32/fraiseexcpt.c @@ -0,0 +1,26 @@ +/* Raise given exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feraiseexcept (int excepts) +{ + __asm__ volatile ("csrs fflags, %0" : : "r" (excepts)); + return 0; +} diff --git a/libm/riscv32/fsetexcptflg.c b/libm/riscv32/fsetexcptflg.c new file mode 100644 index 000000000..f295c18ab --- /dev/null +++ b/libm/riscv32/fsetexcptflg.c @@ -0,0 +1,29 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fexcept_t flags = *flagp; + __asm__ volatile ("csrc fflags, %0" : : "r" (excepts)); + __asm__ volatile ("csrs fflags, %0" : : "r" (flags & excepts)); + + return 0; +} diff --git a/libm/riscv32/ftestexcept.c b/libm/riscv32/ftestexcept.c new file mode 100644 index 000000000..ed3a3e5e0 --- /dev/null +++ b/libm/riscv32/ftestexcept.c @@ -0,0 +1,25 @@ +/* Test exception in current environment. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fetestexcept (int excepts) +{ + return libc_fetestexcept_riscv (excepts); +} diff --git a/libm/riscv32/get-rounding-mode.h b/libm/riscv32/get-rounding-mode.h new file mode 100644 index 000000000..7ab691ac8 --- /dev/null +++ b/libm/riscv32/get-rounding-mode.h @@ -0,0 +1,32 @@ +/* Determine floating-point rounding mode within libc. RISC-V version. + Copyright (C) 2015-2025 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 _RISCV_GET_ROUNDING_MODE_H +#define _RISCV_GET_ROUNDING_MODE_H + +/* Return the floating-point rounding mode. */ + +static inline int +get_rounding_mode (void) +{ + int rm; + __asm__ volatile ("frrm %0" : "=r" (rm)); + return rm; +} + +#endif /* get-rounding-mode.h */ diff --git a/libm/riscv64/Makefile.arch b/libm/riscv64/Makefile.arch new file mode 100644 index 000000000..bd38690be --- /dev/null +++ b/libm/riscv64/Makefile.arch @@ -0,0 +1,16 @@ +# Makefile for uClibc-ng +# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + +ifeq ($(UCLIBC_HAS_FENV),y) +libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c) +libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC)) +endif + +libm_ARCH_OBJS:=$(libm_ARCH_OBJ) + +ifeq ($(DOPIC),y) +libm-a-y+=$(libm_ARCH_OBJS:.o=.os) +else +libm-a-y+=$(libm_ARCH_OBJS) +endif +libm-so-y+=$(libm_ARCH_OBJS:.o=.os) diff --git a/libm/riscv64/fclrexcpt.c b/libm/riscv64/fclrexcpt.c new file mode 100644 index 000000000..849a910fc --- /dev/null +++ b/libm/riscv64/fclrexcpt.c @@ -0,0 +1,26 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feclearexcept (int excepts) +{ + __asm__ volatile ("csrc fflags, %0" : : "r" (excepts)); + return 0; +} diff --git a/libm/riscv64/fegetenv.c b/libm/riscv64/fegetenv.c new file mode 100644 index 000000000..94f3444ac --- /dev/null +++ b/libm/riscv64/fegetenv.c @@ -0,0 +1,28 @@ +/* Store current floating-point environment. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetenv (fenv_t *envp) +{ + _FPU_GETCW (*envp); + + /* Success. */ + return 0; +} diff --git a/libm/riscv64/fegetmode.c b/libm/riscv64/fegetmode.c new file mode 100644 index 000000000..4b0ff270c --- /dev/null +++ b/libm/riscv64/fegetmode.c @@ -0,0 +1,26 @@ +/* Store current floating-point control modes. RISC-V version. + Copyright (C) 2017-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetmode (femode_t *modep) +{ + _FPU_GETCW (*modep); + return 0; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_wait.S b/libm/riscv64/fegetround.c index d3e1549cd..abd13fc7f 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_wait.S +++ b/libm/riscv64/fegetround.c @@ -1,6 +1,5 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. +/* Return current rounding direction. + Copyright (C) 1998-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -13,7 +12,14 @@ 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 - <http://www.gnu.org/licenses/>. */ + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ -#include "../i486/pthread_cond_wait.S" +#include <fenv.h> +#include "fenv_private.h" + +int +fegetround (void) +{ + return riscv_getround (); +} diff --git a/libm/riscv64/feholdexcpt.c b/libm/riscv64/feholdexcpt.c new file mode 100644 index 000000000..5d95a08fe --- /dev/null +++ b/libm/riscv64/feholdexcpt.c @@ -0,0 +1,26 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +feholdexcept (fenv_t *envp) +{ + libc_feholdexcept_riscv (envp); + return 0; +} diff --git a/libm/riscv64/fenv_private.h b/libm/riscv64/fenv_private.h new file mode 100644 index 000000000..9eed4b614 --- /dev/null +++ b/libm/riscv64/fenv_private.h @@ -0,0 +1,156 @@ +/* Private floating point rounding and exceptions handling. RISC-V version. + Copyright (C) 2014-2025 Free Software Foundation, Inc. + + 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 RISCV_FENV_PRIVATE_H +#define RISCV_FENV_PRIVATE_H 1 + +#include <fenv.h> +#include <fpu_control.h> +#include "get-rounding-mode.h" + +static __always_inline int +riscv_getround (void) +{ + return get_rounding_mode (); +} + +static __always_inline void +riscv_setround (int rm) +{ + __asm__ volatile ("fsrm %z0" : : "rJ" (rm)); +} + +static __always_inline int +riscv_getflags (void) +{ + int flags; + __asm__ volatile ("frflags %0" : "=r" (flags)); + return flags; +} + +static __always_inline void +riscv_setflags (int flags) +{ + __asm__ volatile ("fsflags %z0" : : "rJ" (flags)); +} + +static __always_inline void +libc_feholdexcept_riscv (fenv_t *envp) +{ + __asm__ volatile ("csrrc %0, fcsr, %1" : "=r" (*envp) : "i" (FE_ALL_EXCEPT)); +} + +#define libc_feholdexcept libc_feholdexcept_riscv +#define libc_feholdexceptf libc_feholdexcept_riscv +#define libc_feholdexceptl libc_feholdexcept_riscv + +static __always_inline void +libc_fesetround_riscv (int round) +{ + riscv_setround (round); +} + +#define libc_fesetround libc_fesetround_riscv +#define libc_fesetroundf libc_fesetround_riscv +#define libc_fesetroundl libc_fesetround_riscv + +static __always_inline void +libc_feholdexcept_setround_riscv (fenv_t *envp, int round) +{ + libc_feholdexcept_riscv (envp); + libc_fesetround_riscv (round); +} + +#define libc_feholdexcept_setround libc_feholdexcept_setround_riscv +#define libc_feholdexcept_setroundf libc_feholdexcept_setround_riscv +#define libc_feholdexcept_setroundl libc_feholdexcept_setround_riscv + +static __always_inline int +libc_fetestexcept_riscv (int ex) +{ + return riscv_getflags () & ex; +} + +#define libc_fetestexcept libc_fetestexcept_riscv +#define libc_fetestexceptf libc_fetestexcept_riscv +#define libc_fetestexceptl libc_fetestexcept_riscv + +static __always_inline void +libc_fesetenv_riscv (const fenv_t *envp) +{ + long int env = (envp != FE_DFL_ENV ? *envp : 0); + _FPU_SETCW (env); +} + +#define libc_fesetenv libc_fesetenv_riscv +#define libc_fesetenvf libc_fesetenv_riscv +#define libc_fesetenvl libc_fesetenv_riscv +#define libc_feresetround_noex libc_fesetenv_riscv +#define libc_feresetround_noexf libc_fesetenv_riscv +#define libc_feresetround_noexl libc_fesetenv_riscv + +static __always_inline int +libc_feupdateenv_test_riscv (const fenv_t *envp, int ex) +{ + fenv_t env = *envp; + int flags = riscv_getflags (); + __asm__ volatile ("csrw fcsr, %z0" : : "rJ" (env | flags)); + return flags & ex; +} + +#define libc_feupdateenv_test libc_feupdateenv_test_riscv +#define libc_feupdateenv_testf libc_feupdateenv_test_riscv +#define libc_feupdateenv_testl libc_feupdateenv_test_riscv + +static __always_inline void +libc_feupdateenv_riscv (const fenv_t *envp) +{ + long int env = (envp != FE_DFL_ENV ? *envp : 0); + _FPU_SETCW (env | riscv_getflags ()); +} + +#define libc_feupdateenv libc_feupdateenv_riscv +#define libc_feupdateenvf libc_feupdateenv_riscv +#define libc_feupdateenvl libc_feupdateenv_riscv + +static __always_inline void +libc_feholdsetround_riscv (fenv_t *envp, int round) +{ + /* Note this implementation makes an improperly-formatted fenv_t and + so should only be used in conjunction with libc_feresetround. */ + int old_round; + __asm__ volatile ("csrrw %0, frm, %z1" : "=r" (old_round) : "rJ" (round)); + *envp = old_round; +} + +#define libc_feholdsetround libc_feholdsetround_riscv +#define libc_feholdsetroundf libc_feholdsetround_riscv +#define libc_feholdsetroundl libc_feholdsetround_riscv + +static __always_inline void +libc_feresetround_riscv (fenv_t *envp) +{ + /* Note this implementation takes an improperly-formatted fenv_t and + so should only be used in conjunction with libc_feholdsetround. */ + riscv_setround (*envp); +} + +#define libc_feresetround libc_feresetround_riscv +#define libc_feresetroundf libc_feresetround_riscv +#define libc_feresetroundl libc_feresetround_riscv + +#endif diff --git a/libm/riscv64/fesetenv.c b/libm/riscv64/fesetenv.c new file mode 100644 index 000000000..8b7427c18 --- /dev/null +++ b/libm/riscv64/fesetenv.c @@ -0,0 +1,26 @@ +/* Install given floating-point environment. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fesetenv (const fenv_t *envp) +{ + libc_fesetenv_riscv (envp); + return 0; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevellock.S b/libm/riscv64/fesetexcept.c index 59194c712..9c931a1b7 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevellock.S +++ b/libm/riscv64/fesetexcept.c @@ -1,6 +1,5 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. +/* Set given exception flags. RISC-V version. + Copyright (C) 2017-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -14,6 +13,13 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ -#include "../i486/lowlevellock.S" +#include <fenv.h> + +int +fesetexcept (int excepts) +{ + __asm__ volatile ("csrs fflags, %0" : : "r" (excepts)); + return 0; +} diff --git a/libm/riscv64/fesetmode.c b/libm/riscv64/fesetmode.c new file mode 100644 index 000000000..aaaf4480b --- /dev/null +++ b/libm/riscv64/fesetmode.c @@ -0,0 +1,30 @@ +/* Install given floating-point control modes. RISC-V version. + Copyright (C) 2017-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetmode (const femode_t *modep) +{ + __asm__ volatile ("csrc fcsr, %0" : : "r" (~FE_ALL_EXCEPT)); + + if (modep != FE_DFL_MODE) + __asm__ volatile ("csrs fcsr, %0" : : "r" (*modep & ~FE_ALL_EXCEPT)); + + return 0; +} diff --git a/libm/riscv64/fesetround.c b/libm/riscv64/fesetround.c new file mode 100644 index 000000000..a791751d1 --- /dev/null +++ b/libm/riscv64/fesetround.c @@ -0,0 +1,35 @@ +/* Set current rounding direction. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fesetround (int round) +{ + switch (round) + { + case FE_TONEAREST: + case FE_TOWARDZERO: + case FE_DOWNWARD: + case FE_UPWARD: + riscv_setround (round); + return 0; + default: + return round; /* A nonzero value. */ + } +} diff --git a/libm/riscv64/feupdateenv.c b/libm/riscv64/feupdateenv.c new file mode 100644 index 000000000..ea62bd1aa --- /dev/null +++ b/libm/riscv64/feupdateenv.c @@ -0,0 +1,26 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +feupdateenv (const fenv_t *envp) +{ + libc_feupdateenv_riscv (envp); + return 0; +} diff --git a/libm/riscv64/fgetexcptflg.c b/libm/riscv64/fgetexcptflg.c new file mode 100644 index 000000000..ecf513bed --- /dev/null +++ b/libm/riscv64/fgetexcptflg.c @@ -0,0 +1,29 @@ +/* Store current representation for exceptions. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + /* Get the current exceptions. */ + *flagp = riscv_getflags () & excepts; + + /* Success. */ + return 0; +} diff --git a/libm/riscv64/fraiseexcpt.c b/libm/riscv64/fraiseexcpt.c new file mode 100644 index 000000000..f89f983d7 --- /dev/null +++ b/libm/riscv64/fraiseexcpt.c @@ -0,0 +1,26 @@ +/* Raise given exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feraiseexcept (int excepts) +{ + __asm__ volatile ("csrs fflags, %0" : : "r" (excepts)); + return 0; +} diff --git a/libm/riscv64/fsetexcptflg.c b/libm/riscv64/fsetexcptflg.c new file mode 100644 index 000000000..f295c18ab --- /dev/null +++ b/libm/riscv64/fsetexcptflg.c @@ -0,0 +1,29 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fexcept_t flags = *flagp; + __asm__ volatile ("csrc fflags, %0" : : "r" (excepts)); + __asm__ volatile ("csrs fflags, %0" : : "r" (flags & excepts)); + + return 0; +} diff --git a/libm/riscv64/ftestexcept.c b/libm/riscv64/ftestexcept.c new file mode 100644 index 000000000..ed3a3e5e0 --- /dev/null +++ b/libm/riscv64/ftestexcept.c @@ -0,0 +1,25 @@ +/* Test exception in current environment. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fetestexcept (int excepts) +{ + return libc_fetestexcept_riscv (excepts); +} diff --git a/libm/riscv64/get-rounding-mode.h b/libm/riscv64/get-rounding-mode.h new file mode 100644 index 000000000..7ab691ac8 --- /dev/null +++ b/libm/riscv64/get-rounding-mode.h @@ -0,0 +1,32 @@ +/* Determine floating-point rounding mode within libc. RISC-V version. + Copyright (C) 2015-2025 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 _RISCV_GET_ROUNDING_MODE_H +#define _RISCV_GET_ROUNDING_MODE_H + +/* Return the floating-point rounding mode. */ + +static inline int +get_rounding_mode (void) +{ + int rm; + __asm__ volatile ("frrm %0" : "=r" (rm)); + return rm; +} + +#endif /* get-rounding-mode.h */ diff --git a/libm/s_expm1.c b/libm/s_expm1.c index 8e51ae748..85defefa4 100644 --- a/libm/s_expm1.c +++ b/libm/s_expm1.c @@ -159,7 +159,7 @@ double expm1(double x) else {hi = x + ln2_hi; lo = -ln2_lo; k = -1;} } else { - k = invln2*x+((xsb==0)?0.5:-0.5); + k = (int32_t)(invln2*x+((xsb==0)?0.5:-0.5)); t = k; hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ lo = t*ln2_lo; diff --git a/libm/s_nextafter.c b/libm/s_nextafter.c index 73a8ab2be..7eb4ec46e 100644 --- a/libm/s_nextafter.c +++ b/libm/s_nextafter.c @@ -18,6 +18,7 @@ #include "math.h" #include "math_private.h" +#include <float.h> double nextafter(double x, double y) { @@ -68,5 +69,13 @@ double nextafter(double x, double y) return x; } libm_hidden_def(nextafter) +#if LDBL_MANT_DIG == DBL_MANT_DIG strong_alias_untyped(nextafter, nexttoward) libm_hidden_def(nexttoward) +#else +double nexttoward(double x, long double y) +{ + return nextafter(x, y); +} +libm_hidden_def(nexttoward) +#endif diff --git a/libm/sh/sh4/Makefile.arch b/libm/sh/sh4/Makefile.arch index e38e99c15..69996edda 100644 --- a/libm/sh/sh4/Makefile.arch +++ b/libm/sh/sh4/Makefile.arch @@ -8,7 +8,7 @@ ifeq ($(UCLIBC_HAS_FENV),y) libm_ARCH_CSRC:=$(wildcard $(libm_SUBARCH_DIR)/*.c) -libm_ARCH_COBJ:=$(patsubst $(libm_SUBARCH_DIR)/%.c,$(libm_SUBARCH_OUT)/%.o,$(libm_ARCH_SRC)) +libm_ARCH_COBJ:=$(patsubst $(libm_SUBARCH_DIR)/%.c,$(libm_SUBARCH_OUT)/%.o,$(libm_ARCH_CSRC)) libm_ARCH_SSRC:=$(wildcard $(libm_SUBARCH_DIR)/*.S) libm_ARCH_SOBJ:=$(patsubst $(libm_SUBARCH_DIR)/%.S,$(libm_SUBARCH_OUT)/%.o,$(libm_ARCH_SSRC)) endif diff --git a/libm/sh/sh4/fclrexcpt.c b/libm/sh/sh4/fclrexcpt.c new file mode 100644 index 000000000..286b4f36a --- /dev/null +++ b/libm/sh/sh4/fclrexcpt.c @@ -0,0 +1,39 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feclearexcept (int excepts) +{ + fpu_control_t cw; + + /* Mask out unsupported bits/exceptions. */ + excepts &= FE_ALL_EXCEPT; + + /* Read the complete control word. */ + _FPU_GETCW (cw); + + /* Clear exception bits. */ + cw &= ~excepts; + + /* Put the new data in effect. */ + _FPU_SETCW (cw); + + return 0; +} diff --git a/libm/sh/sh4/fedisblxcpt.c b/libm/sh/sh4/fedisblxcpt.c new file mode 100644 index 000000000..69f9ff2c4 --- /dev/null +++ b/libm/sh/sh4/fedisblxcpt.c @@ -0,0 +1,37 @@ +/* Disable floating-point exceptions. + Copyright (C) 2012-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fedisableexcept (int excepts) +{ + fpu_control_t temp, old_exc; + + /* Get the current control register contents. */ + _FPU_GETCW (temp); + + old_exc = (temp >> 5) & FE_ALL_EXCEPT; + + excepts &= FE_ALL_EXCEPT; + + temp &= ~(excepts << 5); + _FPU_SETCW (temp); + + return old_exc; +} diff --git a/libm/sh/sh4/feenablxcpt.c b/libm/sh/sh4/feenablxcpt.c new file mode 100644 index 000000000..bf2b01f0b --- /dev/null +++ b/libm/sh/sh4/feenablxcpt.c @@ -0,0 +1,36 @@ +/* Enable floating-point exceptions. + Copyright (C) 2012-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feenableexcept (int excepts) +{ + fpu_control_t temp, old_flag; + + /* Get current exceptions. */ + _FPU_GETCW (temp); + + old_flag = (temp >> 5) & FE_ALL_EXCEPT; + excepts &= FE_ALL_EXCEPT; + + temp |= excepts << 5; + _FPU_SETCW (temp); + + return old_flag; +} diff --git a/libm/sh/sh4/fegetenv.c b/libm/sh/sh4/fegetenv.c new file mode 100644 index 000000000..d76964f8b --- /dev/null +++ b/libm/sh/sh4/fegetenv.c @@ -0,0 +1,30 @@ +/* Store current floating-point environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetenv (fenv_t *envp) +{ + fpu_control_t temp; + _FPU_GETCW (temp); + + envp->__fpscr = temp; + + return 0; +} diff --git a/libm/sh/sh4/fegetexcept.c b/libm/sh/sh4/fegetexcept.c new file mode 100644 index 000000000..85f783520 --- /dev/null +++ b/libm/sh/sh4/fegetexcept.c @@ -0,0 +1,30 @@ +/* Get enabled floating-point exceptions. + Copyright (C) 2012-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetexcept (void) +{ + fpu_control_t temp; + + /* Get current exceptions. */ + _FPU_GETCW (temp); + + return (temp >> 5) & FE_ALL_EXCEPT; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelrobustlock.S b/libm/sh/sh4/fegetmode.c index 6103f2ee4..16deb5183 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelrobustlock.S +++ b/libm/sh/sh4/fegetmode.c @@ -1,6 +1,5 @@ -/* Copyright (C) 2002, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. +/* Store current floating-point control modes. SH4 version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -14,6 +13,14 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ -#include "../i486/lowlevelrobustlock.S" +#include <fenv.h> +#include <fpu_control.h> + +int +fegetmode (femode_t *modep) +{ + _FPU_GETCW (*modep); + return 0; +} diff --git a/libm/sh/sh4/fegetround.c b/libm/sh/sh4/fegetround.c new file mode 100644 index 000000000..b7c26eb6f --- /dev/null +++ b/libm/sh/sh4/fegetround.c @@ -0,0 +1,30 @@ +/* Return current rounding direction. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetround (void) +{ + fpu_control_t cw; + + /* Get control word. */ + _FPU_GETCW (cw); + + return cw & 0x1; +} diff --git a/libm/sh/sh4/feholdexcpt.c b/libm/sh/sh4/feholdexcpt.c index 70b51e8dd..fc462b403 100644 --- a/libm/sh/sh4/feholdexcpt.c +++ b/libm/sh/sh4/feholdexcpt.c @@ -1,13 +1,19 @@ -/* - * - * Copyright (c) 2007 STMicroelectronics Ltd - * Filippo Arcidiacono (filippo.arcidiacono@st.com) - * - * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - * - * Taken from glibc 2.6 - * - */ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> #include <fpu_control.h> @@ -15,15 +21,20 @@ int feholdexcept (fenv_t *envp) { - unsigned long int temp; + fpu_control_t temp; /* Store the environment. */ _FPU_GETCW (temp); envp->__fpscr = temp; - /* Now set all exceptions to non-stop. */ + /* Clear the status flags. */ temp &= ~FE_ALL_EXCEPT; + + /* Now set all exceptions to non-stop. */ + temp &= ~(FE_ALL_EXCEPT << 5); + _FPU_SETCW (temp); - return 1; + /* Success. */ + return 0; } diff --git a/libm/sh/sh4/fesetenv.c b/libm/sh/sh4/fesetenv.c index c5cfc1d51..6a9a68090 100644 --- a/libm/sh/sh4/fesetenv.c +++ b/libm/sh/sh4/fesetenv.c @@ -1,13 +1,19 @@ -/* - * - * Copyright (c) 2007 STMicroelectronics Ltd - * Filippo Arcidiacono (filippo.arcidiacono@st.com) - * - * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - * - * Taken from glibc 2.6 - * - */ +/* Install given floating-point environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> #include <fpu_control.h> @@ -19,7 +25,7 @@ fesetenv (const fenv_t *envp) _FPU_SETCW (_FPU_DEFAULT); else { - unsigned long int temp = envp->__fpscr; + fpu_control_t temp = envp->__fpscr; _FPU_SETCW (temp); } return 0; diff --git a/libm/sh/sh4/fesetexcept.c b/libm/sh/sh4/fesetexcept.c new file mode 100644 index 000000000..eceb0bb4f --- /dev/null +++ b/libm/sh/sh4/fesetexcept.c @@ -0,0 +1,31 @@ +/* Set given exception flags. SH4 version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetexcept (int excepts) +{ + fpu_control_t temp; + + _FPU_GETCW (temp); + temp |= (excepts & FE_ALL_EXCEPT); + _FPU_SETCW (temp); + + return 0; +} diff --git a/libm/sh/sh4/fesetmode.c b/libm/sh/sh4/fesetmode.c new file mode 100644 index 000000000..073da0984 --- /dev/null +++ b/libm/sh/sh4/fesetmode.c @@ -0,0 +1,37 @@ +/* Install given floating-point control modes. SH4 version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +#define FPU_STATUS 0x3f07c + +int +fesetmode (const femode_t *modep) +{ + fpu_control_t fpscr; + + _FPU_GETCW (fpscr); + fpscr &= FPU_STATUS; + if (modep == FE_DFL_MODE) + fpscr |= _FPU_DEFAULT; + else + fpscr |= *modep & ~FPU_STATUS; + _FPU_SETCW (fpscr); + + return 0; +} diff --git a/libm/sh/sh4/fesetround.c b/libm/sh/sh4/fesetround.c new file mode 100644 index 000000000..144eca86f --- /dev/null +++ b/libm/sh/sh4/fesetround.c @@ -0,0 +1,40 @@ +/* Set current rounding direction. + Copyright (C) 1998-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fesetround (int round) +{ + fpu_control_t cw; + + if ((round & ~0x1) != 0) + /* ROUND is no valid rounding mode. */ + return 1; + + /* Get current state. */ + _FPU_GETCW (cw); + + /* Set rounding bits. */ + cw &= ~0x1; + cw |= round; + /* Set new state. */ + _FPU_SETCW (cw); + + return 0; +} diff --git a/libm/sh/sh4/feupdateenv.c b/libm/sh/sh4/feupdateenv.c new file mode 100644 index 000000000..cb7e95259 --- /dev/null +++ b/libm/sh/sh4/feupdateenv.c @@ -0,0 +1,36 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 2012-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +feupdateenv (const fenv_t *envp) +{ + fpu_control_t temp; + + _FPU_GETCW (temp); + temp = (temp & FE_ALL_EXCEPT); + + /* Raise the saved exception. Incidentally for us the implementation + defined format of the values in objects of type fexcept_t is the + same as the ones specified using the FE_* constants. */ + fesetenv (envp); + feraiseexcept ((int) temp); + + return 0; +} diff --git a/libm/sh/sh4/fgetexcptflg.c b/libm/sh/sh4/fgetexcptflg.c new file mode 100644 index 000000000..308b5ad44 --- /dev/null +++ b/libm/sh/sh4/fgetexcptflg.c @@ -0,0 +1,37 @@ +/* Store current representation for exceptions. + Copyright (C) 2013-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + fpu_control_t temp; + + /* Get the current exceptions. */ + _FPU_GETCW (temp); + + /* We only save the relevant bits here. In particular, care has to be + taken with the CAUSE bits, as an inadvertent restore later on could + generate unexpected exceptions. */ + + *flagp = temp & excepts & FE_ALL_EXCEPT; + + /* Success. */ + return 0; +} diff --git a/libm/sh/sh4/fraiseexcpt.c b/libm/sh/sh4/fraiseexcpt.c new file mode 100644 index 000000000..1ed495b7a --- /dev/null +++ b/libm/sh/sh4/fraiseexcpt.c @@ -0,0 +1,70 @@ +/* Raise given exceptions. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <float.h> +#include <fpu_control.h> +#include <math.h> + +int +feraiseexcept (int excepts) +{ + if (excepts == 0) + return 0; + + /* Raise exceptions represented by EXPECTS. */ + + if (excepts & FE_INEXACT) + { + double d = 1.0, x = 3.0; + __asm__ __volatile__ ("fdiv %1, %0" : "+d" (d) : "d" (x)); + } + + if (excepts & FE_UNDERFLOW) + { + long double d = LDBL_MIN, x = 10; + __asm__ __volatile__ ("fdiv %1, %0" : "+d" (d) : "d" (x)); + } + + if (excepts & FE_OVERFLOW) + { + long double d = LDBL_MAX; + __asm__ __volatile__ ("fmul %0, %0" : "+d" (d) : "d" (d)); + } + + if (excepts & FE_DIVBYZERO) + { + double d = 1.0, x = 0.0; + __asm__ __volatile__ ("fdiv %1, %0" : "+d" (d) : "d" (x)); + } + + if (excepts & FE_INVALID) + { + double d = HUGE_VAL, x = 0.0; + __asm__ __volatile__ ("fmul %1, %0" : "+d" (d) : "d" (x)); + } + + { + /* Restore flag fields. */ + fpu_control_t cw; + _FPU_GETCW (cw); + cw |= (excepts & FE_ALL_EXCEPT); + _FPU_SETCW (cw); + } + + return 0; +} diff --git a/libm/sh/sh4/fsetexcptflg.c b/libm/sh/sh4/fsetexcptflg.c new file mode 100644 index 000000000..8fcb94973 --- /dev/null +++ b/libm/sh/sh4/fsetexcptflg.c @@ -0,0 +1,38 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <math.h> +#include <fpu_control.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fpu_control_t temp; + + /* Get the current environment. */ + _FPU_GETCW (temp); + + /* Set the desired exception mask. */ + temp &= ~(excepts & FE_ALL_EXCEPT); + temp |= (*flagp & excepts & FE_ALL_EXCEPT); + + /* Save state back to the FPU. */ + _FPU_SETCW (temp); + + return 0; +} diff --git a/libm/sh/sh4/ftestexcept.c b/libm/sh/sh4/ftestexcept.c new file mode 100644 index 000000000..edc523426 --- /dev/null +++ b/libm/sh/sh4/ftestexcept.c @@ -0,0 +1,30 @@ +/* Test exception in current environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <fpu_control.h> + +int +fetestexcept (int excepts) +{ + fpu_control_t temp; + + /* Get current exceptions. */ + _FPU_GETCW (temp); + + return temp & excepts & FE_ALL_EXCEPT; +} diff --git a/libm/sparc/Makefile.arch b/libm/sparc/Makefile.arch new file mode 100644 index 000000000..bd38690be --- /dev/null +++ b/libm/sparc/Makefile.arch @@ -0,0 +1,16 @@ +# Makefile for uClibc-ng +# Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + +ifeq ($(UCLIBC_HAS_FENV),y) +libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c) +libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC)) +endif + +libm_ARCH_OBJS:=$(libm_ARCH_OBJ) + +ifeq ($(DOPIC),y) +libm-a-y+=$(libm_ARCH_OBJS:.o=.os) +else +libm-a-y+=$(libm_ARCH_OBJS) +endif +libm-so-y+=$(libm_ARCH_OBJS:.o=.os) diff --git a/libm/sparc/fclrexcpt.c b/libm/sparc/fclrexcpt.c new file mode 100644 index 000000000..ae344658d --- /dev/null +++ b/libm/sparc/fclrexcpt.c @@ -0,0 +1,34 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +feclearexcept (int excepts) +{ + fenv_t tmp; + + __fenv_stfsr (tmp); + + tmp &= ~(excepts & FE_ALL_EXCEPT); + + __fenv_ldfsr (tmp); + + /* Success. */ + return 0; +} diff --git a/libm/sparc/fedisblxcpt.c b/libm/sparc/fedisblxcpt.c new file mode 100644 index 000000000..9bc546f2d --- /dev/null +++ b/libm/sparc/fedisblxcpt.c @@ -0,0 +1,34 @@ +/* Disable floating-point exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fedisableexcept (int excepts) +{ + fenv_t new_exc, old_exc; + + __fenv_stfsr (new_exc); + + old_exc = (new_exc >> 18) & FE_ALL_EXCEPT; + new_exc &= ~(((fenv_t)excepts & FE_ALL_EXCEPT) << 18); + + __fenv_ldfsr (new_exc); + + return old_exc; +} diff --git a/libm/sparc/feenablxcpt.c b/libm/sparc/feenablxcpt.c new file mode 100644 index 000000000..ab88e7e42 --- /dev/null +++ b/libm/sparc/feenablxcpt.c @@ -0,0 +1,34 @@ +/* Enable floating-point exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +feenableexcept (int excepts) +{ + fenv_t new_exc, old_exc; + + __fenv_stfsr (new_exc); + + old_exc = (new_exc >> 18) & FE_ALL_EXCEPT; + new_exc |= (((fenv_t)excepts & FE_ALL_EXCEPT) << 18); + + __fenv_ldfsr (new_exc); + + return old_exc; +} diff --git a/libm/sparc/fegetenv.c b/libm/sparc/fegetenv.c new file mode 100644 index 000000000..883012932 --- /dev/null +++ b/libm/sparc/fegetenv.c @@ -0,0 +1,28 @@ +/* Store current floating-point environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fegetenv (fenv_t *envp) +{ + __fenv_stfsr (*envp); + + /* Success. */ + return 0; +} diff --git a/libm/sparc/fegetexcept.c b/libm/sparc/fegetexcept.c new file mode 100644 index 000000000..53dfdab8c --- /dev/null +++ b/libm/sparc/fegetexcept.c @@ -0,0 +1,28 @@ +/* Get enabled floating-point exceptions. + Copyright (C) 2000-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fegetexcept (void) +{ + fenv_t exc; + __fenv_stfsr (exc); + + return (exc >> 18) & FE_ALL_EXCEPT; +} diff --git a/libm/sparc/fegetmode.c b/libm/sparc/fegetmode.c new file mode 100644 index 000000000..0bb9ba111 --- /dev/null +++ b/libm/sparc/fegetmode.c @@ -0,0 +1,26 @@ +/* Store current floating-point control modes. SPARC version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fegetmode (femode_t *modep) +{ + __fenv_stfsr (*modep); + return 0; +} diff --git a/libm/sparc/fegetround.c b/libm/sparc/fegetround.c new file mode 100644 index 000000000..bb53a735e --- /dev/null +++ b/libm/sparc/fegetround.c @@ -0,0 +1,29 @@ +/* Return current rounding direction. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fegetround (void) +{ + fenv_t tmp; + + __fenv_stfsr (tmp); + + return tmp & __FE_ROUND_MASK; +} diff --git a/libm/sparc/feholdexcpt.c b/libm/sparc/feholdexcpt.c new file mode 100644 index 000000000..7d712198b --- /dev/null +++ b/libm/sparc/feholdexcpt.c @@ -0,0 +1,34 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +feholdexcept (fenv_t *envp) +{ + fenv_t tmp; + + __fenv_stfsr (*envp); + + /* Set all exceptions to non-stop and clear all exceptions. */ + tmp = *envp & ~((0x1f << 23) | FE_ALL_EXCEPT); + + __fenv_ldfsr (tmp); + + return 0; +} diff --git a/libm/sparc/fenv_private.h b/libm/sparc/fenv_private.h new file mode 100644 index 000000000..b888d8442 --- /dev/null +++ b/libm/sparc/fenv_private.h @@ -0,0 +1,187 @@ +#ifndef SPARC_FENV_PRIVATE_H +#define SPARC_FENV_PRIVATE_H 1 + +#include <fenv.h> +#include <fpu_control.h> + +/* For internal use only: access the fp state register. */ +#define __fenv_stfsr(X) _FPU_GETCW (X) +#define __fenv_ldfsr(X) _FPU_SETCW (X) + +static __always_inline void +libc_feholdexcept (fenv_t *e) +{ + fenv_t etmp; + __fenv_stfsr(etmp); + *(e) = etmp; + etmp = etmp & ~((0x1f << 23) | FE_ALL_EXCEPT); + __fenv_ldfsr(etmp); +} + +static __always_inline void +libc_fesetround (int r) +{ + fenv_t etmp; + __fenv_stfsr(etmp); + etmp = (etmp & ~__FE_ROUND_MASK) | (r); + __fenv_ldfsr(etmp); +} + +static __always_inline void +libc_feholdexcept_setround (fenv_t *e, int r) +{ + fenv_t etmp; + __fenv_stfsr(etmp); + *(e) = etmp; + etmp = etmp & ~((0x1f << 23) | FE_ALL_EXCEPT); + etmp = (etmp & ~__FE_ROUND_MASK) | (r); + __fenv_ldfsr(etmp); +} + +static __always_inline int +libc_fetestexcept (int e) +{ + fenv_t etmp; + __fenv_stfsr(etmp); + return etmp & (e) & FE_ALL_EXCEPT; +} + +static __always_inline void +libc_fesetenv (fenv_t *e) +{ + __fenv_ldfsr(*e); +} + +static __always_inline int +libc_feupdateenv_test (fenv_t *e, int ex) +{ + fenv_t etmp; + + __fenv_stfsr(etmp); + etmp &= FE_ALL_EXCEPT; + + __fenv_ldfsr(*e); + + feraiseexcept (etmp); + + return etmp & ex; +} + +static __always_inline void +libc_feupdateenv (fenv_t *e) +{ + libc_feupdateenv_test (e, 0); +} + +static __always_inline void +libc_feholdsetround (fenv_t *e, int r) +{ + fenv_t etmp; + __fenv_stfsr(etmp); + *(e) = etmp; + etmp = (etmp & ~__FE_ROUND_MASK) | (r); + __fenv_ldfsr(etmp); +} + +static __always_inline void +libc_feresetround (fenv_t *e) +{ + fenv_t etmp; + __fenv_stfsr(etmp); + etmp = (etmp & ~__FE_ROUND_MASK) | (*e & __FE_ROUND_MASK); + __fenv_ldfsr(etmp); +} + +#define libc_feholdexceptf libc_feholdexcept +#define libc_fesetroundf libc_fesetround +#define libc_feholdexcept_setroundf libc_feholdexcept_setround +#define libc_fetestexceptf libc_fetestexcept +#define libc_fesetenvf libc_fesetenv +#define libc_feupdateenv_testf libc_feupdateenv_test +#define libc_feupdateenvf libc_feupdateenv +#define libc_feholdsetroundf libc_feholdsetround +#define libc_feresetroundf libc_feresetround +#define libc_feholdexcept libc_feholdexcept +#define libc_fesetround libc_fesetround +#define libc_feholdexcept_setround libc_feholdexcept_setround +#define libc_fetestexcept libc_fetestexcept +#define libc_fesetenv libc_fesetenv +#define libc_feupdateenv_test libc_feupdateenv_test +#define libc_feupdateenv libc_feupdateenv +#define libc_feholdsetround libc_feholdsetround +#define libc_feresetround libc_feresetround +#define libc_feholdexceptl libc_feholdexcept +#define libc_fesetroundl libc_fesetround +#define libc_feholdexcept_setroundl libc_feholdexcept_setround +#define libc_fetestexceptl libc_fetestexcept +#define libc_fesetenvl libc_fesetenv +#define libc_feupdateenv_testl libc_feupdateenv_test +#define libc_feupdateenvl libc_feupdateenv +#define libc_feholdsetroundl libc_feholdsetround +#define libc_feresetroundl libc_feresetround + +/* We have support for rounding mode context. */ +#define HAVE_RM_CTX 1 + +static __always_inline void +libc_feholdexcept_setround_sparc_ctx (struct rm_ctx *ctx, int round) +{ + fenv_t new; + + __fenv_stfsr(ctx->env); + new = ctx->env & ~((0x1f << 23) | FE_ALL_EXCEPT); + new = (new & ~__FE_ROUND_MASK) | round; + if (unlikely (new != ctx->env)) + { + __fenv_ldfsr(new); + ctx->updated_status = true; + } + else + ctx->updated_status = false; +} + +static __always_inline void +libc_fesetenv_sparc_ctx (struct rm_ctx *ctx) +{ + libc_fesetenv(&ctx->env); +} + +static __always_inline void +libc_feupdateenv_sparc_ctx (struct rm_ctx *ctx) +{ + if (unlikely (ctx->updated_status)) + libc_feupdateenv_test (&ctx->env, 0); +} + +static __always_inline void +libc_feholdsetround_sparc_ctx (struct rm_ctx *ctx, int round) +{ + fenv_t new; + + __fenv_stfsr(ctx->env); + new = (ctx->env & ~__FE_ROUND_MASK) | round; + if (unlikely (new != ctx->env)) + { + __fenv_ldfsr(new); + ctx->updated_status = true; + } + else + ctx->updated_status = false; +} +#define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_sparc_ctx +#define libc_feholdexcept_setroundf_ctx libc_feholdexcept_setround_sparc_ctx +#define libc_feholdexcept_setroundl_ctx libc_feholdexcept_setround_sparc_ctx +#define libc_fesetenv_ctx libc_fesetenv_sparc_ctx +#define libc_fesetenvf_ctx libc_fesetenv_sparc_ctx +#define libc_fesetenvl_ctx libc_fesetenv_sparc_ctx +#define libc_feupdateenv_ctx libc_feupdateenv_sparc_ctx +#define libc_feupdateenvf_ctx libc_feupdateenv_sparc_ctx +#define libc_feupdateenvl_ctx libc_feupdateenv_sparc_ctx +#define libc_feresetround_ctx libc_feupdateenv_sparc_ctx +#define libc_feresetroundf_ctx libc_feupdateenv_sparc_ctx +#define libc_feresetroundl_ctx libc_feupdateenv_sparc_ctx +#define libc_feholdsetround_ctx libc_feholdsetround_sparc_ctx +#define libc_feholdsetroundf_ctx libc_feholdsetround_sparc_ctx +#define libc_feholdsetroundl_ctx libc_feholdsetround_sparc_ctx + +#endif /* SPARC_FENV_PRIVATE_H */ diff --git a/libm/sparc/fesetenv.c b/libm/sparc/fesetenv.c new file mode 100644 index 000000000..d6f3dc5f5 --- /dev/null +++ b/libm/sparc/fesetenv.c @@ -0,0 +1,45 @@ +/* Install given floating-point environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fesetenv (const fenv_t *envp) +{ + fenv_t dummy; + + /* Put these constants in memory explicitly, so as to cope with a + -fPIC bug as of gcc 970624. Making them automatic is quicker + than loading up the pic register in this instance. */ + + if (envp == FE_DFL_ENV) + { + dummy = 0; + envp = &dummy; + } + else if (envp == FE_NOMASK_ENV) + { + dummy = 0x1f << 23; + envp = &dummy; + } + + __fenv_ldfsr (*envp); + + /* Success. */ + return 0; +} diff --git a/libm/sparc/fesetexcept.c b/libm/sparc/fesetexcept.c new file mode 100644 index 000000000..02210b691 --- /dev/null +++ b/libm/sparc/fesetexcept.c @@ -0,0 +1,31 @@ +/* Set given exception flags. SPARC version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fesetexcept (int excepts) +{ + fenv_t tmp; + + __fenv_stfsr (tmp); + tmp |= excepts & FE_ALL_EXCEPT; + __fenv_ldfsr (tmp); + + return 0; +} diff --git a/libm/sparc/fesetmode.c b/libm/sparc/fesetmode.c new file mode 100644 index 000000000..e72b3d9df --- /dev/null +++ b/libm/sparc/fesetmode.c @@ -0,0 +1,38 @@ +/* Install given floating-point control modes. SPARC version. + Copyright (C) 2016-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" +#include <fpu_control.h> + +#define FPU_CONTROL_BITS 0xcfc00000UL + +int +fesetmode (const femode_t *modep) +{ + femode_t fsr; + + __fenv_stfsr (fsr); + fsr &= ~FPU_CONTROL_BITS; + if (modep == FE_DFL_MODE) + fsr |= _FPU_DEFAULT; + else + fsr |= *modep & FPU_CONTROL_BITS; + __fenv_ldfsr (fsr); + + return 0; +} diff --git a/libm/sparc/fesetround.c b/libm/sparc/fesetround.c new file mode 100644 index 000000000..ba3a4e50f --- /dev/null +++ b/libm/sparc/fesetround.c @@ -0,0 +1,36 @@ +/* Set current rounding direction. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fesetround (int round) +{ + fenv_t tmp; + + if ((round & ~__FE_ROUND_MASK) != 0) + /* ROUND is no valid rounding mode. */ + return 1; + + __fenv_stfsr (tmp); + tmp &= ~__FE_ROUND_MASK; + tmp |= round; + __fenv_ldfsr (tmp); + + return 0; +} diff --git a/libm/sparc/feupdateenv.c b/libm/sparc/feupdateenv.c new file mode 100644 index 000000000..272536cf3 --- /dev/null +++ b/libm/sparc/feupdateenv.c @@ -0,0 +1,40 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +feupdateenv (const fenv_t *envp) +{ + fexcept_t tmp; + + /* Save current exceptions. */ + __fenv_stfsr (tmp); + tmp &= FE_ALL_EXCEPT; + + /* Install new environment. */ + fesetenv (envp); + + /* Raise the saved exception. Incidentally for us the implementation + defined format of the values in objects of type fexcept_t is the + same as the ones specified using the FE_* constants. */ + feraiseexcept ((int) tmp); + + /* Success. */ + return 0; +} diff --git a/libm/sparc/fgetexcptflg.c b/libm/sparc/fgetexcptflg.c new file mode 100644 index 000000000..d8568906e --- /dev/null +++ b/libm/sparc/fgetexcptflg.c @@ -0,0 +1,33 @@ +/* Store current representation for exceptions. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + fexcept_t tmp; + + /* Get the current exceptions. */ + __fenv_stfsr (tmp); + + *flagp = tmp & excepts & FE_ALL_EXCEPT; + + /* Success. */ + return 0; +} diff --git a/libm/sparc/fpu_control.h b/libm/sparc/fpu_control.h new file mode 100644 index 000000000..542f9fb1b --- /dev/null +++ b/libm/sparc/fpu_control.h @@ -0,0 +1,75 @@ +/* FPU control word bits. SPARC version. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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 _FPU_CONTROL_H +#define _FPU_CONTROL_H 1 + + +#include <features.h> +#include <bits/wordsize.h> + +/* masking of interrupts */ +#define _FPU_MASK_IM 0x08000000 +#define _FPU_MASK_OM 0x04000000 +#define _FPU_MASK_UM 0x02000000 +#define _FPU_MASK_ZM 0x01000000 +#define _FPU_MASK_PM 0x00800000 + +/* precision control */ +#define _FPU_EXTENDED 0x00000000 /* RECOMMENDED */ +#define _FPU_DOUBLE 0x20000000 +#define _FPU_80BIT 0x30000000 +#define _FPU_SINGLE 0x10000000 /* DO NOT USE */ + +/* rounding control / Sparc */ +#define _FPU_RC_DOWN 0xc0000000 +#define _FPU_RC_UP 0x80000000 +#define _FPU_RC_ZERO 0x40000000 +#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */ + +#define _FPU_RESERVED 0x303e0000 /* Reserved bits in cw */ + + +/* Now two recommended cw */ + +/* Linux and IEEE default: + - extended precision + - rounding to nearest + - no exceptions */ +#define _FPU_DEFAULT 0x0 +#define _FPU_IEEE 0x0 + +/* Type of the control word. */ +typedef unsigned long int fpu_control_t; + +#if __WORDSIZE == 64 +# define _FPU_GETCW(cw) __asm__ __volatile__ ("stx %%fsr,%0" : "=m" (*&cw)) +# define _FPU_SETCW(cw) __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (*&cw)) +#else +# ifdef __leon__ + /* Prevent stfsr from being placed directly after other fp instruction. */ +# define _FPU_GETCW(cw) __asm__ __volatile__ ("nop; st %%fsr,%0" : "=m" (*&cw)) +# else +# define _FPU_GETCW(cw) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (*&cw)) +# endif +# define _FPU_SETCW(cw) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (*&cw)) +#endif + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif /* fpu_control.h */ diff --git a/libm/sparc/fraiseexcpt.c b/libm/sparc/fraiseexcpt.c new file mode 100644 index 000000000..72e151fe6 --- /dev/null +++ b/libm/sparc/fraiseexcpt.c @@ -0,0 +1,81 @@ +/* Raise given exceptions. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include <float.h> +#include <math.h> +#include "math-barriers.h" + +int +feraiseexcept (int excepts) +{ + static const struct { + double zero, one, max, min, pi; + } c = { + 0.0, 1.0, DBL_MAX, DBL_MIN, M_PI + }; + double d; + + /* Raise exceptions represented by EXPECTS. But we must raise only + one signal at a time. It is important the if the overflow/underflow + exception and the inexact exception are given at the same time, + the overflow/underflow exception follows the inexact exception. */ + + /* First: invalid exception. */ + if ((FE_INVALID & excepts) != 0) + { + /* One example of an invalid operation is 0/0. */ + __asm__ ("" : "=e" (d) : "0" (c.zero)); + d /= c.zero; + math_force_eval (d); + } + + /* Next: division by zero. */ + if ((FE_DIVBYZERO & excepts) != 0) + { + __asm__ ("" : "=e" (d) : "0" (c.one)); + d /= c.zero; + math_force_eval (d); + } + + /* Next: overflow. */ + if ((FE_OVERFLOW & excepts) != 0) + { + __asm__ ("" : "=e" (d) : "0" (c.max)); + d *= d; + math_force_eval (d); + } + + /* Next: underflow. */ + if ((FE_UNDERFLOW & excepts) != 0) + { + __asm__ ("" : "=e" (d) : "0" (c.min)); + d *= d; + math_force_eval (d); + } + + /* Last: inexact. */ + if ((FE_INEXACT & excepts) != 0) + { + __asm__ ("" : "=e" (d) : "0" (c.one)); + d /= c.pi; + math_force_eval (d); + } + + /* Success. */ + return 0; +} diff --git a/libm/sparc/fsetexcptflg.c b/libm/sparc/fsetexcptflg.c new file mode 100644 index 000000000..4b3b6ae68 --- /dev/null +++ b/libm/sparc/fsetexcptflg.c @@ -0,0 +1,36 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" +#include <math.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fenv_t tmp; + + __fenv_stfsr (tmp); + + tmp &= ~(excepts & FE_ALL_EXCEPT); + tmp |= *flagp & excepts & FE_ALL_EXCEPT; + + __fenv_ldfsr (tmp); + + /* Success. */ + return 0; +} diff --git a/libm/sparc/ftestexcept.c b/libm/sparc/ftestexcept.c new file mode 100644 index 000000000..1fe87bb36 --- /dev/null +++ b/libm/sparc/ftestexcept.c @@ -0,0 +1,29 @@ +/* Test exception in current environment. + Copyright (C) 1997-2025 Free Software Foundation, Inc. + + 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.h> +#include "fenv_private.h" + +int +fetestexcept (int excepts) +{ + fenv_t tmp; + + __fenv_stfsr (tmp); + + return tmp & excepts & FE_ALL_EXCEPT; +} diff --git a/libm/sparc/math-barriers.h b/libm/sparc/math-barriers.h new file mode 100644 index 000000000..4b02ff47b --- /dev/null +++ b/libm/sparc/math-barriers.h @@ -0,0 +1,36 @@ +/* Control when floating-point expressions are evaluated. Generic version. + Copyright (C) 2007-2025 Free Software Foundation, Inc. + + 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 _MATH_BARRIERS_H +#define _MATH_BARRIERS_H 1 + +/* math_opt_barrier evaluates and returns its floating-point argument + and ensures that the evaluation of any expression using the result + of math_opt_barrier is not moved before the call. math_force_eval + ensures that its floating-point argument is evaluated for its side + effects even if its value is apparently unused, and that the + evaluation of its argument is not moved after the call. Both these + macros are used to ensure the correct ordering of floating-point + expression evaluations with respect to accesses to the + floating-point environment. */ + +#define math_opt_barrier(x) \ + ({ __typeof (x) __x = (x); __asm ("" : "+m" (__x)); __x; }) +#define math_force_eval(x) \ + ({ __typeof (x) __x = (x); __asm __volatile__ ("" : : "m" (__x)); }) + +#endif /* math-barriers.h */ diff --git a/libm/w_cabs.c b/libm/w_cabs.c index b2592484c..546b6affa 100644 --- a/libm/w_cabs.c +++ b/libm/w_cabs.c @@ -17,7 +17,7 @@ libm_hidden_def(cabs) libm_hidden_proto(cabsf) float cabsf(float _Complex z) { - return (float) hypot(__real__ z, __imag__ z); + return (float) hypot((double)__real__ z, (double)__imag__ z); } libm_hidden_def(cabsf) diff --git a/libpthread/linuxthreads/Makefile.in b/libpthread/linuxthreads/Makefile.in index ffdd5d4eb..cc2a5f285 100644 --- a/libpthread/linuxthreads/Makefile.in +++ b/libpthread/linuxthreads/Makefile.in @@ -16,6 +16,8 @@ libpthread_OUT := $(top_builddir)libpthread/linuxthreads -include $(libpthread_DIR)/sysdeps/$(TARGET_ARCH)/Makefile.arch +CFLAGS-signals.c = -fexceptions -fasynchronous-unwind-tables + libpthread_SRC := \ attr.c cancel.c condvar.c errno.c events.c join.c lockfile.c manager.c \ mutex.c pt-machine.c ptfork.c pthread.c ptlongjmp.c \ diff --git a/libpthread/linuxthreads/sysdeps/pthread/not-cancel.h b/libpthread/linuxthreads/sysdeps/pthread/not-cancel.h index bbdb0739c..6d7c4d70a 100644 --- a/libpthread/linuxthreads/sysdeps/pthread/not-cancel.h +++ b/libpthread/linuxthreads/sysdeps/pthread/not-cancel.h @@ -19,6 +19,7 @@ #include <sys/types.h> #include <sysdep.h> +#include <time.h> /* Uncancelable open. */ #if defined __NR_openat && !defined __NR_open @@ -104,6 +105,7 @@ extern int __openat64_nocancel (int fd, const char *fname, int oflag, # define nanosleep_not_cancel(requested_time, remaining) \ INLINE_SYSCALL (nanosleep, 2, requested_time, remaining) #else +extern int __nanosleep_nocancel (const struct timespec *requested_time, struct timespec *remaining); # define nanosleep_not_cancel(requested_time, remaining) \ __nanosleep_nocancel (requested_time, remaining) #endif diff --git a/libpthread/linuxthreads/sysdeps/riscv32/pt-machine.h b/libpthread/linuxthreads/sysdeps/riscv32/pt-machine.h new file mode 100644 index 000000000..38f0d8eff --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/riscv32/pt-machine.h @@ -0,0 +1,61 @@ +/* + * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + */ + +#ifndef _PT_MACHINE_H +#define _PT_MACHINE_H 1 +#include <features.h> + +#ifndef PT_EI +# define PT_EI __extern_always_inline +#endif + +#define HAS_COMPARE_AND_SWAP +PT_EI int +__compare_and_swap (long int *p, long int oldval, long int newval) +{ + long int ret, temp; + + __asm__ __volatile__ + ("/* Inline compare & swap */\n" + "1:\n\t" + "lr.w %1,%2\n\t" + "li %0,0\n\t" + "bne %1,%3,2f\n\t" + "li %0,1\n\t" + "sc.w %1,%4,%2\n\t" + "bnez %1,1b\n" + "2:\n\t" + "/* End compare & swap */" + : "=&r" (ret), "=&r" (temp), "+A" (*p) + : "r" (oldval), "r" (newval) + : "memory"); + + return ret; +} + +extern long int testandset (int *spinlock); + +PT_EI long int +testandset (int *spinlock) +{ + unsigned int old = 1; + int tmp = 1; + + __asm__ __volatile__ ( + "amoswap.w %0, %2, %1" + : "=r" (old), "+A" (*spinlock) + : "r" (tmp) + : "memory"); + + return old; +} + +/* Get some notion of the current stack. Need not be exactly the top + of the stack, just something somewhere in the current frame. */ +#define CURRENT_STACK_FRAME stack_pointer +register char * stack_pointer __asm__ ("sp"); + +#else +#error PT_MACHINE already defined +#endif /* pt-machine.h */ diff --git a/libpthread/nptl/allocatestack.c b/libpthread/nptl/allocatestack.c index 7ef884543..941ef22f0 100644 --- a/libpthread/nptl/allocatestack.c +++ b/libpthread/nptl/allocatestack.c @@ -24,6 +24,7 @@ #include <unistd.h> #include <sys/mman.h> #include <sys/param.h> +#include <dl-tls.h> #include <tls.h> #include <lowlevellock.h> #include <link.h> @@ -241,6 +242,10 @@ get_cached_stack (size_t *sizep, void **memp) /* Clear the DTV. */ dtv_t *dtv = GET_DTV (TLS_TPADJ (result)); + for (size_t cnt = 0; cnt < dtv[-1].counter; ++cnt) + if (! dtv[1 + cnt].pointer.is_static + && dtv[1 + cnt].pointer.val != TLS_DTV_UNALLOCATED) + free (dtv[1 + cnt].pointer.val); memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t)); /* Re-initialize the TLS. */ diff --git a/libpthread/nptl/pthread_create.c b/libpthread/nptl/pthread_create.c index 697af20e0..3d83a51fe 100644 --- a/libpthread/nptl/pthread_create.c +++ b/libpthread/nptl/pthread_create.c @@ -551,11 +551,11 @@ pthread_create ( return 0; } - + /* Information for libthread_db. */ #include "../nptl_db/db_info.c" - + /* If pthread_create is present, libgcc_eh.a and libsupc++.a expects some other POSIX thread functions to be present as well. */ PTHREAD_STATIC_FN_REQUIRE (pthread_mutex_lock) diff --git a/libpthread/nptl/sysdeps/arc/dl-tls.h b/libpthread/nptl/sysdeps/arc/dl-tls.h index 34e54e4d3..e81c0c187 100644 --- a/libpthread/nptl/sysdeps/arc/dl-tls.h +++ b/libpthread/nptl/sysdeps/arc/dl-tls.h @@ -26,3 +26,6 @@ typedef struct extern void *__tls_get_addr (tls_index *ti); + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/arm/dl-tls.h b/libpthread/nptl/sysdeps/arm/dl-tls.h index a728455e4..a79ea7160 100644 --- a/libpthread/nptl/sysdeps/arm/dl-tls.h +++ b/libpthread/nptl/sysdeps/arm/dl-tls.h @@ -26,3 +26,6 @@ typedef struct extern void *__tls_get_addr (tls_index *ti); + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/csky/dl-tls.h b/libpthread/nptl/sysdeps/csky/dl-tls.h index ebf1a7dc3..7171d47ea 100644 --- a/libpthread/nptl/sysdeps/csky/dl-tls.h +++ b/libpthread/nptl/sysdeps/csky/dl-tls.h @@ -14,3 +14,5 @@ typedef struct extern void *__tls_get_addr (tls_index *ti); +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/generic/dl-tls.c b/libpthread/nptl/sysdeps/generic/dl-tls.c index 7d25e4706..7b7991be8 100644 --- a/libpthread/nptl/sysdeps/generic/dl-tls.c +++ b/libpthread/nptl/sysdeps/generic/dl-tls.c @@ -45,8 +45,6 @@ to allow dynamic loading of modules defining IE-model TLS data. */ # define TLS_STATIC_SURPLUS 64 + DL_NNS * 100 -/* Value used for dtv entries for which the allocation is delayed. */ -# define TLS_DTV_UNALLOCATED ((void *) -1l) #ifndef SHARED extern dtv_t static_dtv; diff --git a/libpthread/nptl/sysdeps/i386/dl-tls.h b/libpthread/nptl/sysdeps/i386/dl-tls.h index 32495c1e0..004082407 100644 --- a/libpthread/nptl/sysdeps/i386/dl-tls.h +++ b/libpthread/nptl/sysdeps/i386/dl-tls.h @@ -59,3 +59,6 @@ strong_alias (___tls_get_addr, ___tls_get_addr_internal) # endif #endif + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/metag/dl-tls.h b/libpthread/nptl/sysdeps/metag/dl-tls.h index 81632e057..811d6254f 100644 --- a/libpthread/nptl/sysdeps/metag/dl-tls.h +++ b/libpthread/nptl/sysdeps/metag/dl-tls.h @@ -26,3 +26,6 @@ typedef struct extern void *__tls_get_addr (tls_index *ti); + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/microblaze/dl-tls.h b/libpthread/nptl/sysdeps/microblaze/dl-tls.h index 5613e21e2..ded8714bd 100644 --- a/libpthread/nptl/sysdeps/microblaze/dl-tls.h +++ b/libpthread/nptl/sysdeps/microblaze/dl-tls.h @@ -24,3 +24,6 @@ typedef struct } tls_index; extern void *__tls_get_addr (tls_index *ti); + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/mips/dl-tls.h b/libpthread/nptl/sysdeps/mips/dl-tls.h index e26aa388b..63ec2bc00 100644 --- a/libpthread/nptl/sysdeps/mips/dl-tls.h +++ b/libpthread/nptl/sysdeps/mips/dl-tls.h @@ -43,3 +43,6 @@ extern void *__tls_get_addr (tls_index *ti); # define GET_ADDR_OFFSET (ti->ti_offset + TLS_DTV_OFFSET) # define __TLS_GET_ADDR(__ti) (__tls_get_addr (__ti) - TLS_DTV_OFFSET) + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/nds32/dl-tls.h b/libpthread/nptl/sysdeps/nds32/dl-tls.h index 3b11e7f42..f0107cacb 100644 --- a/libpthread/nptl/sysdeps/nds32/dl-tls.h +++ b/libpthread/nptl/sysdeps/nds32/dl-tls.h @@ -50,7 +50,7 @@ struct tlsdesc_dynamic_arg extern void *__tls_get_addr (tls_index *ti); extern ptrdiff_t attribute_hidden - _dl_tlsdesc_return(struct tlsdesc_dynamic_arg *); + _dl_tlsdesc_return(struct tlsdesc *); extern void *_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset); extern ptrdiff_t attribute_hidden diff --git a/libpthread/nptl/sysdeps/or1k/dl-tls.h b/libpthread/nptl/sysdeps/or1k/dl-tls.h index 5613e21e2..ded8714bd 100644 --- a/libpthread/nptl/sysdeps/or1k/dl-tls.h +++ b/libpthread/nptl/sysdeps/or1k/dl-tls.h @@ -24,3 +24,6 @@ typedef struct } tls_index; extern void *__tls_get_addr (tls_index *ti); + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/powerpc/dl-tls.h b/libpthread/nptl/sysdeps/powerpc/dl-tls.h index c322ade60..ae50098c7 100644 --- a/libpthread/nptl/sysdeps/powerpc/dl-tls.h +++ b/libpthread/nptl/sysdeps/powerpc/dl-tls.h @@ -46,3 +46,6 @@ extern void *__tls_get_addr (tls_index *ti); # define GET_ADDR_OFFSET (ti->ti_offset + TLS_DTV_OFFSET) # define __TLS_GET_ADDR(__ti) (__tls_get_addr (__ti) - TLS_DTV_OFFSET) #endif + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/riscv32/dl-tls.h b/libpthread/nptl/sysdeps/riscv32/dl-tls.h index 31991be0d..4124b7c78 100644 --- a/libpthread/nptl/sysdeps/riscv32/dl-tls.h +++ b/libpthread/nptl/sysdeps/riscv32/dl-tls.h @@ -32,3 +32,6 @@ extern void *__tls_get_addr (tls_index *ti); #define GET_ADDR_OFFSET (ti->ti_offset + TLS_DTV_OFFSET) #define __TLS_GET_ADDR(__ti) (__tls_get_addr (__ti) - TLS_DTV_OFFSET) + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/riscv64/dl-tls.h b/libpthread/nptl/sysdeps/riscv64/dl-tls.h index 31991be0d..4124b7c78 100644 --- a/libpthread/nptl/sysdeps/riscv64/dl-tls.h +++ b/libpthread/nptl/sysdeps/riscv64/dl-tls.h @@ -32,3 +32,6 @@ extern void *__tls_get_addr (tls_index *ti); #define GET_ADDR_OFFSET (ti->ti_offset + TLS_DTV_OFFSET) #define __TLS_GET_ADDR(__ti) (__tls_get_addr (__ti) - TLS_DTV_OFFSET) + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/sh/dl-tls.h b/libpthread/nptl/sysdeps/sh/dl-tls.h index f5f90beaf..e0d13eec4 100644 --- a/libpthread/nptl/sysdeps/sh/dl-tls.h +++ b/libpthread/nptl/sysdeps/sh/dl-tls.h @@ -26,3 +26,6 @@ typedef struct extern void *__tls_get_addr (tls_index *ti); + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/sparc/dl-tls.h b/libpthread/nptl/sysdeps/sparc/dl-tls.h index 7d9e8f0f7..aac9d5b30 100644 --- a/libpthread/nptl/sysdeps/sparc/dl-tls.h +++ b/libpthread/nptl/sysdeps/sparc/dl-tls.h @@ -26,3 +26,6 @@ typedef struct extern void *__tls_get_addr (tls_index *ti); + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile.arch index ee38a6988..c244b1f62 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile.arch +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile.arch @@ -5,9 +5,8 @@ # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -libpthread_linux_arch_SSRC = pthread_spin_unlock.S pthread_once.S -libpthread_linux_arch_CSRC = pthread_spin_init.c +libpthread_linux_arch_SSRC = pthread_once.S +libpthread_linux_arch_CSRC = libc_linux_arch_CSRC = fork.c -ASFLAGS += -DUSE___THREAD diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S deleted file mode 100644 index ff9a7847f..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S +++ /dev/null @@ -1,464 +0,0 @@ -/* Copyright (C) 2002-2004, 2006, 2007, 2009 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <pthread-errnos.h> -#include <bits/kernel-features.h> -#include <lowlevellock.h> -#include <tcb-offsets.h> - - .text - -#ifdef __ASSUME_PRIVATE_FUTEX -# define LOAD_PRIVATE_FUTEX_WAIT(reg) \ - movl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg -# define LOAD_PRIVATE_FUTEX_WAKE(reg) \ - movl $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg -# define LOAD_FUTEX_WAIT(reg) \ - xorl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg -# define LOAD_FUTEX_WAIT_ABS(reg) \ - xorl $(FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME), reg -# define LOAD_FUTEX_WAKE(reg) \ - xorl $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg -#else -# if FUTEX_WAIT == 0 -# define LOAD_PRIVATE_FUTEX_WAIT(reg) \ - movl %gs:PRIVATE_FUTEX, reg -# else -# define LOAD_PRIVATE_FUTEX_WAIT(reg) \ - movl %gs:PRIVATE_FUTEX, reg ; \ - orl $FUTEX_WAIT, reg -# endif -# define LOAD_PRIVATE_FUTEX_WAKE(reg) \ - movl %gs:PRIVATE_FUTEX, reg ; \ - orl $FUTEX_WAKE, reg -# if FUTEX_WAIT == 0 -# define LOAD_FUTEX_WAIT(reg) \ - xorl $FUTEX_PRIVATE_FLAG, reg ; \ - andl %gs:PRIVATE_FUTEX, reg -# else -# define LOAD_FUTEX_WAIT(reg) \ - xorl $FUTEX_PRIVATE_FLAG, reg ; \ - andl %gs:PRIVATE_FUTEX, reg ; \ - orl $FUTEX_WAIT, reg -# endif -# define LOAD_FUTEX_WAIT_ABS(reg) \ - xorl $FUTEX_PRIVATE_FLAG, reg ; \ - andl %gs:PRIVATE_FUTEX, reg ; \ - orl $FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME, reg -# define LOAD_FUTEX_WAKE(reg) \ - xorl $FUTEX_PRIVATE_FLAG, reg ; \ - andl %gs:PRIVATE_FUTEX, reg ; \ - orl $FUTEX_WAKE, reg -#endif - - .globl __lll_lock_wait_private - .type __lll_lock_wait_private,@function - .hidden __lll_lock_wait_private -#ifndef IS_IN_libpthread - .weak __lll_lock_wait_private -#endif - .align 16 -__lll_lock_wait_private: - cfi_startproc - pushl %edx - cfi_adjust_cfa_offset(4) - pushl %ebx - cfi_adjust_cfa_offset(4) - pushl %esi - cfi_adjust_cfa_offset(4) - cfi_offset(%edx, -8) - cfi_offset(%ebx, -12) - cfi_offset(%esi, -16) - - movl $2, %edx - movl %ecx, %ebx - xorl %esi, %esi /* No timeout. */ - LOAD_PRIVATE_FUTEX_WAIT (%ecx) - - cmpl %edx, %eax /* NB: %edx == 2 */ - jne 2f - -1: movl $SYS_futex, %eax - ENTER_KERNEL - -2: movl %edx, %eax - xchgl %eax, (%ebx) /* NB: lock is implied */ - - testl %eax, %eax - jnz 1b - - popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - popl %edx - cfi_adjust_cfa_offset(-4) - cfi_restore(%edx) - ret - cfi_endproc - .size __lll_lock_wait_private,.-__lll_lock_wait_private - -#ifdef NOT_IN_libc - .globl __lll_lock_wait - .type __lll_lock_wait,@function - .hidden __lll_lock_wait - .align 16 -__lll_lock_wait: - cfi_startproc - pushl %edx - cfi_adjust_cfa_offset(4) - pushl %ebx - cfi_adjust_cfa_offset(4) - pushl %esi - cfi_adjust_cfa_offset(4) - cfi_offset(%edx, -8) - cfi_offset(%ebx, -12) - cfi_offset(%esi, -16) - - movl %edx, %ebx - movl $2, %edx - xorl %esi, %esi /* No timeout. */ - LOAD_FUTEX_WAIT (%ecx) - - cmpl %edx, %eax /* NB: %edx == 2 */ - jne 2f - -1: movl $SYS_futex, %eax - ENTER_KERNEL - -2: movl %edx, %eax - xchgl %eax, (%ebx) /* NB: lock is implied */ - - testl %eax, %eax - jnz 1b - - popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - popl %edx - cfi_adjust_cfa_offset(-4) - cfi_restore(%edx) - ret - cfi_endproc - .size __lll_lock_wait,.-__lll_lock_wait - - /* %ecx: futex - %esi: flags - %edx: timeout - %eax: futex value - */ - .globl __lll_timedlock_wait - .type __lll_timedlock_wait,@function - .hidden __lll_timedlock_wait - .align 16 -__lll_timedlock_wait: - cfi_startproc - pushl %ebp - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%ebp, 0) - pushl %ebx - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%ebx, 0) - -# ifndef __ASSUME_FUTEX_CLOCK_REALTIME -# ifdef __PIC__ - LOAD_PIC_REG (bx) - cmpl $0, __have_futex_clock_realtime@GOTOFF(%ebx) -# else - cmpl $0, __have_futex_clock_realtime -# endif - je .Lreltmo -# endif - - movl %ecx, %ebx - movl %esi, %ecx - movl %edx, %esi - movl $0xffffffff, %ebp - LOAD_FUTEX_WAIT_ABS (%ecx) - - movl $2, %edx - cmpl %edx, %eax - jne 2f - -1: movl $SYS_futex, %eax - movl $2, %edx - ENTER_KERNEL - -2: xchgl %edx, (%ebx) /* NB: lock is implied */ - - testl %edx, %edx - jz 3f - - cmpl $-ETIMEDOUT, %eax - je 4f - cmpl $-EINVAL, %eax - jne 1b -4: movl %eax, %edx - negl %edx - -3: movl %edx, %eax -7: popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - popl %ebp - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebp) - ret - -# ifndef __ASSUME_FUTEX_CLOCK_REALTIME -.Lreltmo: - /* Check for a valid timeout value. */ - cmpl $1000000000, 4(%edx) - jae 3f - - pushl %esi - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%esi, 0) - pushl %edi - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%edi, 0) - - /* Stack frame for the timespec and timeval structs. */ - subl $8, %esp - cfi_adjust_cfa_offset(8) - - movl %ecx, %ebp - movl %edx, %edi - - movl $2, %edx - xchgl %edx, (%ebp) - - test %edx, %edx - je 6f - -1: - /* Get current time. */ - movl %esp, %ebx - xorl %ecx, %ecx - movl $__NR_gettimeofday, %eax - ENTER_KERNEL - - /* Compute relative timeout. */ - movl 4(%esp), %eax - movl $1000, %edx - mul %edx /* Milli seconds to nano seconds. */ - movl (%edi), %ecx - movl 4(%edi), %edx - subl (%esp), %ecx - subl %eax, %edx - jns 4f - addl $1000000000, %edx - subl $1, %ecx -4: testl %ecx, %ecx - js 2f /* Time is already up. */ - - /* Store relative timeout. */ - movl %ecx, (%esp) - movl %edx, 4(%esp) - - /* Futex call. */ - movl %ebp, %ebx - movl $2, %edx - movl %esp, %esi - movl 16(%esp), %ecx - LOAD_FUTEX_WAIT (%ecx) - movl $SYS_futex, %eax - ENTER_KERNEL - - /* NB: %edx == 2 */ - xchgl %edx, (%ebp) - - testl %edx, %edx - je 6f - - cmpl $-ETIMEDOUT, %eax - jne 1b -2: movl $ETIMEDOUT, %edx - -6: addl $8, %esp - cfi_adjust_cfa_offset(-8) - popl %edi - cfi_adjust_cfa_offset(-4) - cfi_restore(%edi) - popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) -7: popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - popl %ebp - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebp) - movl %edx, %eax - ret - -3: movl $EINVAL, %edx - jmp 7b -# endif - cfi_endproc - .size __lll_timedlock_wait,.-__lll_timedlock_wait -#endif - - .globl __lll_unlock_wake_private - .type __lll_unlock_wake_private,@function - .hidden __lll_unlock_wake_private -#ifndef IS_IN_libpthread - .weak __lll_unlock_wake_private -#endif - .align 16 -__lll_unlock_wake_private: - cfi_startproc - pushl %ebx - cfi_adjust_cfa_offset(4) - pushl %ecx - cfi_adjust_cfa_offset(4) - pushl %edx - cfi_adjust_cfa_offset(4) - cfi_offset(%ebx, -8) - cfi_offset(%ecx, -12) - cfi_offset(%edx, -16) - - movl %eax, %ebx - movl $0, (%eax) - LOAD_PRIVATE_FUTEX_WAKE (%ecx) - movl $1, %edx /* Wake one thread. */ - movl $SYS_futex, %eax - ENTER_KERNEL - - popl %edx - cfi_adjust_cfa_offset(-4) - cfi_restore(%edx) - popl %ecx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ecx) - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - ret - cfi_endproc - .size __lll_unlock_wake_private,.-__lll_unlock_wake_private - -#ifdef NOT_IN_libc - .globl __lll_unlock_wake - .type __lll_unlock_wake,@function - .hidden __lll_unlock_wake - .align 16 -__lll_unlock_wake: - cfi_startproc - pushl %ebx - cfi_adjust_cfa_offset(4) - pushl %ecx - cfi_adjust_cfa_offset(4) - pushl %edx - cfi_adjust_cfa_offset(4) - cfi_offset(%ebx, -8) - cfi_offset(%ecx, -12) - cfi_offset(%edx, -16) - - movl %eax, %ebx - movl $0, (%eax) - LOAD_FUTEX_WAKE (%ecx) - movl $1, %edx /* Wake one thread. */ - movl $SYS_futex, %eax - ENTER_KERNEL - - popl %edx - cfi_adjust_cfa_offset(-4) - cfi_restore(%edx) - popl %ecx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ecx) - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - ret - cfi_endproc - .size __lll_unlock_wake,.-__lll_unlock_wake - - .globl __lll_timedwait_tid - .type __lll_timedwait_tid,@function - .hidden __lll_timedwait_tid - .align 16 -__lll_timedwait_tid: - pushl %edi - pushl %esi - pushl %ebx - pushl %ebp - - movl %eax, %ebp - movl %edx, %edi - subl $8, %esp - - /* Get current time. */ -2: movl %esp, %ebx - xorl %ecx, %ecx - movl $__NR_gettimeofday, %eax - ENTER_KERNEL - - /* Compute relative timeout. */ - movl 4(%esp), %eax - movl $1000, %edx - mul %edx /* Milli seconds to nano seconds. */ - movl (%edi), %ecx - movl 4(%edi), %edx - subl (%esp), %ecx - subl %eax, %edx - jns 5f - addl $1000000000, %edx - subl $1, %ecx -5: testl %ecx, %ecx - js 6f /* Time is already up. */ - - movl %ecx, (%esp) /* Store relative timeout. */ - movl %edx, 4(%esp) - - movl (%ebp), %edx - testl %edx, %edx - jz 4f - - movl %esp, %esi - /* XXX The kernel so far uses global futex for the wakeup at - all times. */ - xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */ - movl %ebp, %ebx - movl $SYS_futex, %eax - ENTER_KERNEL - - cmpl $0, (%ebx) - jne 1f -4: xorl %eax, %eax - -3: addl $8, %esp - popl %ebp - popl %ebx - popl %esi - popl %edi - ret - -1: cmpl $-ETIMEDOUT, %eax - jne 2b -6: movl $ETIMEDOUT, %eax - jmp 3b - .size __lll_timedwait_tid,.-__lll_timedwait_tid -#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S deleted file mode 100644 index 7196d40e4..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S +++ /dev/null @@ -1,233 +0,0 @@ -/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <pthread-errnos.h> -#include <lowlevellock.h> -#include <lowlevelrobustlock.h> -#include <bits/kernel-features.h> -#include <tls.h> - - .text - -#define FUTEX_WAITERS 0x80000000 -#define FUTEX_OWNER_DIED 0x40000000 - -#ifdef __ASSUME_PRIVATE_FUTEX -# define LOAD_FUTEX_WAIT(reg) \ - xorl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg -#else -# if FUTEX_WAIT == 0 -# define LOAD_FUTEX_WAIT(reg) \ - xorl $FUTEX_PRIVATE_FLAG, reg ; \ - andl %gs:PRIVATE_FUTEX, reg -# else -# define LOAD_FUTEX_WAIT(reg) \ - xorl $FUTEX_PRIVATE_FLAG, reg ; \ - andl %gs:PRIVATE_FUTEX, reg ; \ - orl $FUTEX_WAIT, reg -# endif -#endif - - .globl __lll_robust_lock_wait - .type __lll_robust_lock_wait,@function - .hidden __lll_robust_lock_wait - .align 16 -__lll_robust_lock_wait: - cfi_startproc - pushl %edx - cfi_adjust_cfa_offset(4) - pushl %ebx - cfi_adjust_cfa_offset(4) - pushl %esi - cfi_adjust_cfa_offset(4) - cfi_offset(%edx, -8) - cfi_offset(%ebx, -12) - cfi_offset(%esi, -16) - - movl %edx, %ebx - xorl %esi, %esi /* No timeout. */ - LOAD_FUTEX_WAIT (%ecx) - -4: movl %eax, %edx - orl $FUTEX_WAITERS, %edx - - testl $FUTEX_OWNER_DIED, %eax - jnz 3f - - cmpl %edx, %eax /* NB: %edx == 2 */ - je 1f - - LOCK - cmpxchgl %edx, (%ebx) - jnz 2f - -1: movl $SYS_futex, %eax - ENTER_KERNEL - - movl (%ebx), %eax - -2: test %eax, %eax - jne 4b - - movl %gs:TID, %edx - orl $FUTEX_WAITERS, %edx - LOCK - cmpxchgl %edx, (%ebx) - jnz 4b - /* NB: %eax == 0 */ - -3: popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - popl %edx - cfi_adjust_cfa_offset(-4) - cfi_restore(%edx) - ret - cfi_endproc - .size __lll_robust_lock_wait,.-__lll_robust_lock_wait - - - .globl __lll_robust_timedlock_wait - .type __lll_robust_timedlock_wait,@function - .hidden __lll_robust_timedlock_wait - .align 16 -__lll_robust_timedlock_wait: - cfi_startproc - /* Check for a valid timeout value. */ - cmpl $1000000000, 4(%edx) - jae 3f - - pushl %edi - cfi_adjust_cfa_offset(4) - pushl %esi - cfi_adjust_cfa_offset(4) - pushl %ebx - cfi_adjust_cfa_offset(4) - pushl %ebp - cfi_adjust_cfa_offset(4) - cfi_offset(%edi, -8) - cfi_offset(%esi, -12) - cfi_offset(%ebx, -16) - cfi_offset(%ebp, -20) - - /* Stack frame for the timespec and timeval structs. */ - subl $12, %esp - cfi_adjust_cfa_offset(12) - - movl %ecx, %ebp - movl %edx, %edi - -1: movl %eax, 8(%esp) - - /* Get current time. */ - movl %esp, %ebx - xorl %ecx, %ecx - movl $__NR_gettimeofday, %eax - ENTER_KERNEL - - /* Compute relative timeout. */ - movl 4(%esp), %eax - movl $1000, %edx - mul %edx /* Milli seconds to nano seconds. */ - movl (%edi), %ecx - movl 4(%edi), %edx - subl (%esp), %ecx - subl %eax, %edx - jns 4f - addl $1000000000, %edx - subl $1, %ecx -4: testl %ecx, %ecx - js 8f /* Time is already up. */ - - /* Store relative timeout. */ - movl %ecx, (%esp) - movl %edx, 4(%esp) - - movl %ebp, %ebx - - movl 8(%esp), %edx - movl %edx, %eax - orl $FUTEX_WAITERS, %edx - - testl $FUTEX_OWNER_DIED, %eax - jnz 6f - - cmpl %eax, %edx - je 2f - - LOCK - cmpxchgl %edx, (%ebx) - movl $0, %ecx /* Must use mov to avoid changing cc. */ - jnz 5f - -2: - /* Futex call. */ - movl %esp, %esi - movl 20(%esp), %ecx - LOAD_FUTEX_WAIT (%ecx) - movl $SYS_futex, %eax - ENTER_KERNEL - movl %eax, %ecx - - movl (%ebx), %eax - -5: testl %eax, %eax - jne 7f - - movl %gs:TID, %edx - orl $FUTEX_WAITERS, %edx - LOCK - cmpxchgl %edx, (%ebx) - jnz 7f - -6: addl $12, %esp - cfi_adjust_cfa_offset(-12) - popl %ebp - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebp) - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) - popl %edi - cfi_adjust_cfa_offset(-4) - cfi_restore(%edi) - ret - -3: movl $EINVAL, %eax - ret - - cfi_adjust_cfa_offset(28) - cfi_offset(%edi, -8) - cfi_offset(%esi, -12) - cfi_offset(%ebx, -16) - cfi_offset(%ebp, -20) - /* Check whether the time expired. */ -7: cmpl $-ETIMEDOUT, %ecx - jne 1b - -8: movl $ETIMEDOUT, %eax - jmp 6b - cfi_endproc - .size __lll_robust_timedlock_wait,.-__lll_robust_timedlock_wait diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S deleted file mode 100644 index 5443a3805..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <lowlevellock.h> -#include <lowlevelbarrier.h> - - .text - - .globl pthread_barrier_wait - .type pthread_barrier_wait,@function - .align 16 -pthread_barrier_wait: - cfi_startproc - pushl %ebx - cfi_adjust_cfa_offset(4) - cfi_offset(%ebx, -8) - - movl 8(%esp), %ebx - - /* Get the mutex. */ - movl $1, %edx - xorl %eax, %eax - LOCK - cmpxchgl %edx, MUTEX(%ebx) - jnz 1f - - /* One less waiter. If this was the last one needed wake - everybody. */ -2: subl $1, LEFT(%ebx) - je 3f - - /* There are more threads to come. */ - pushl %esi - cfi_adjust_cfa_offset(4) - cfi_offset(%esi, -12) - -#if CURR_EVENT == 0 - movl (%ebx), %edx -#else - movl CURR_EVENT(%ebx), %edx -#endif - - /* Release the mutex. */ - LOCK - subl $1, MUTEX(%ebx) - jne 6f - - /* Wait for the remaining threads. The call will return immediately - if the CURR_EVENT memory has meanwhile been changed. */ -7: -#if FUTEX_WAIT == 0 - movl PRIVATE(%ebx), %ecx -#else - movl $FUTEX_WAIT, %ecx - orl PRIVATE(%ebx), %ecx -#endif - xorl %esi, %esi -8: movl $SYS_futex, %eax - ENTER_KERNEL - - /* Don't return on spurious wakeups. The syscall does not change - any register except %eax so there is no need to reload any of - them. */ -#if CURR_EVENT == 0 - cmpl %edx, (%ebx) -#else - cmpl %edx, CURR_EVENT(%ebx) -#endif - je 8b - - /* Increment LEFT. If this brings the count back to the - initial count unlock the object. */ - movl $1, %edx - movl INIT_COUNT(%ebx), %ecx - LOCK - xaddl %edx, LEFT(%ebx) - subl $1, %ecx - cmpl %ecx, %edx - jne 10f - - /* Release the mutex. We cannot release the lock before - waking the waiting threads since otherwise a new thread might - arrive and gets waken up, too. */ - LOCK - subl $1, MUTEX(%ebx) - jne 9f - - /* Note: %esi is still zero. */ -10: movl %esi, %eax /* != PTHREAD_BARRIER_SERIAL_THREAD */ - - popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - ret - - cfi_adjust_cfa_offset(4) - cfi_offset(%ebx, -8) - - /* The necessary number of threads arrived. */ -3: -#if CURR_EVENT == 0 - addl $1, (%ebx) -#else - addl $1, CURR_EVENT(%ebx) -#endif - - /* Wake up all waiters. The count is a signed number in the kernel - so 0x7fffffff is the highest value. */ - movl $0x7fffffff, %edx - movl $FUTEX_WAKE, %ecx - orl PRIVATE(%ebx), %ecx - movl $SYS_futex, %eax - ENTER_KERNEL - - /* Increment LEFT. If this brings the count back to the - initial count unlock the object. */ - movl $1, %edx - movl INIT_COUNT(%ebx), %ecx - LOCK - xaddl %edx, LEFT(%ebx) - subl $1, %ecx - cmpl %ecx, %edx - jne 5f - - /* Release the mutex. We cannot release the lock before - waking the waiting threads since otherwise a new thread might - arrive and gets waken up, too. */ - LOCK - subl $1, MUTEX(%ebx) - jne 4f - -5: orl $-1, %eax /* == PTHREAD_BARRIER_SERIAL_THREAD */ - - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - ret - - cfi_adjust_cfa_offset(4) - cfi_offset(%ebx, -8) -1: movl PRIVATE(%ebx), %ecx - leal MUTEX(%ebx), %edx - xorl $LLL_SHARED, %ecx - call __lll_lock_wait - jmp 2b - -4: movl PRIVATE(%ebx), %ecx - leal MUTEX(%ebx), %eax - xorl $LLL_SHARED, %ecx - call __lll_unlock_wake - jmp 5b - - cfi_adjust_cfa_offset(4) - cfi_offset(%esi, -12) -6: movl PRIVATE(%ebx), %ecx - leal MUTEX(%ebx), %eax - xorl $LLL_SHARED, %ecx - call __lll_unlock_wake - jmp 7b - -9: movl PRIVATE(%ebx), %ecx - leal MUTEX(%ebx), %eax - xorl $LLL_SHARED, %ecx - call __lll_unlock_wake - jmp 10b - cfi_endproc - .size pthread_barrier_wait,.-pthread_barrier_wait diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S deleted file mode 100644 index d53aa7282..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S +++ /dev/null @@ -1,238 +0,0 @@ -/* Copyright (C) 2002,2003,2004,2006,2007,2009 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <lowlevellock.h> -#include <lowlevelcond.h> -#include <bits/kernel-features.h> -#include <pthread-pi-defines.h> -#include <pthread-errnos.h> -#include <tls.h> - - .text - - /* int pthread_cond_broadcast (pthread_cond_t *cond) */ - .globl __pthread_cond_broadcast - .type __pthread_cond_broadcast, @function - .protected __pthread_cond_broadcast - .align 16 -__pthread_cond_broadcast: - cfi_startproc - pushl %ebx - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%ebx, 0) - pushl %esi - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%esi, 0) - pushl %edi - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%edi, 0) - pushl %ebp - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%ebp, 0) - cfi_remember_state - - movl 20(%esp), %ebx - - /* Get internal lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if cond_lock == 0 - cmpxchgl %edx, (%ebx) -#else - cmpxchgl %edx, cond_lock(%ebx) -#endif - jnz 1f - -2: addl $cond_futex, %ebx - movl total_seq+4-cond_futex(%ebx), %eax - movl total_seq-cond_futex(%ebx), %ebp - cmpl wakeup_seq+4-cond_futex(%ebx), %eax - ja 3f - jb 4f - cmpl wakeup_seq-cond_futex(%ebx), %ebp - jna 4f - - /* Cause all currently waiting threads to recognize they are - woken up. */ -3: movl %ebp, wakeup_seq-cond_futex(%ebx) - movl %eax, wakeup_seq-cond_futex+4(%ebx) - movl %ebp, woken_seq-cond_futex(%ebx) - movl %eax, woken_seq-cond_futex+4(%ebx) - addl %ebp, %ebp - addl $1, broadcast_seq-cond_futex(%ebx) - movl %ebp, (%ebx) - - /* Get the address of the mutex used. */ - movl dep_mutex-cond_futex(%ebx), %edi - - /* Unlock. */ - LOCK - subl $1, cond_lock-cond_futex(%ebx) - jne 7f - - /* Don't use requeue for pshared condvars. */ -8: cmpl $-1, %edi - je 9f - - /* Do not use requeue for pshared condvars. */ - testl $PS_BIT, MUTEX_KIND(%edi) - jne 9f - - /* Requeue to a non-robust PI mutex if the PI bit is set and - the robust bit is not set. */ - movl MUTEX_KIND(%edi), %eax - andl $(ROBUST_BIT|PI_BIT), %eax - cmpl $PI_BIT, %eax - je 81f - - /* Wake up all threads. */ -#ifdef __ASSUME_PRIVATE_FUTEX - movl $(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), %ecx -#else - movl %gs:PRIVATE_FUTEX, %ecx - orl $FUTEX_CMP_REQUEUE, %ecx -#endif - movl $SYS_futex, %eax - movl $0x7fffffff, %esi - movl $1, %edx - /* Get the address of the futex involved. */ -# if MUTEX_FUTEX != 0 - addl $MUTEX_FUTEX, %edi -# endif -/* FIXME: Until Ingo fixes 4G/4G vDSO, 6 arg syscalls are broken for sysenter. - ENTER_KERNEL */ - int $0x80 - - /* For any kind of error, which mainly is EAGAIN, we try again - with WAKE. The general test also covers running on old - kernels. */ - cmpl $0xfffff001, %eax - jae 9f - -6: xorl %eax, %eax - popl %ebp - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebp) - popl %edi - cfi_adjust_cfa_offset(-4) - cfi_restore(%edi) - popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - ret - - cfi_restore_state - -81: movl $(FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx - movl $SYS_futex, %eax - movl $0x7fffffff, %esi - movl $1, %edx - /* Get the address of the futex involved. */ -# if MUTEX_FUTEX != 0 - addl $MUTEX_FUTEX, %edi -# endif - int $0x80 - - /* For any kind of error, which mainly is EAGAIN, we try again - with WAKE. The general test also covers running on old - kernels. */ - cmpl $0xfffff001, %eax - jb 6b - jmp 9f - - /* Initial locking failed. */ -1: -#if cond_lock == 0 - movl %ebx, %edx -#else - leal cond_lock(%ebx), %edx -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_lock_wait - jmp 2b - - .align 16 - /* Unlock. */ -4: LOCK - subl $1, cond_lock-cond_futex(%ebx) - je 6b - - /* Unlock in loop requires wakeup. */ -5: leal cond_lock-cond_futex(%ebx), %eax -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex-cond_futex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_unlock_wake - jmp 6b - - /* Unlock in loop requires wakeup. */ -7: leal cond_lock-cond_futex(%ebx), %eax -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex-cond_futex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_unlock_wake - jmp 8b - -9: /* The futex requeue functionality is not available. */ - movl $0x7fffffff, %edx -#if FUTEX_PRIVATE_FLAG > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex-cond_futex(%ebx) - sete %cl - subl $1, %ecx -#ifdef __ASSUME_PRIVATE_FUTEX - andl $FUTEX_PRIVATE_FLAG, %ecx -#else - andl %gs:PRIVATE_FUTEX, %ecx -#endif - addl $FUTEX_WAKE, %ecx - movl $SYS_futex, %eax - ENTER_KERNEL - jmp 6b - cfi_endproc - .size __pthread_cond_broadcast, .-__pthread_cond_broadcast -weak_alias(__pthread_cond_broadcast, pthread_cond_broadcast) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S deleted file mode 100644 index d831a6bf5..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S +++ /dev/null @@ -1,215 +0,0 @@ -/* Copyright (C) 2002,2003,2004,2005,2007,2009 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <lowlevellock.h> -#include <lowlevelcond.h> -#include <bits/kernel-features.h> -#include <pthread-pi-defines.h> -#include <pthread-errnos.h> -#include <tls.h> - - - .text - - /* int pthread_cond_signal (pthread_cond_t *cond) */ - .globl __pthread_cond_signal - .type __pthread_cond_signal, @function - .protected __pthread_cond_signal - .align 16 -__pthread_cond_signal: - - cfi_startproc - pushl %ebx - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%ebx, 0) - pushl %edi - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%edi, 0) - cfi_remember_state - - movl 12(%esp), %edi - - /* Get internal lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if cond_lock == 0 - cmpxchgl %edx, (%edi) -#else - cmpxchgl %edx, cond_lock(%edi) -#endif - jnz 1f - -2: leal cond_futex(%edi), %ebx - movl total_seq+4(%edi), %eax - movl total_seq(%edi), %ecx - cmpl wakeup_seq+4(%edi), %eax -#if cond_lock != 0 - /* Must use leal to preserve the flags. */ - leal cond_lock(%edi), %edi -#endif - ja 3f - jb 4f - cmpl wakeup_seq-cond_futex(%ebx), %ecx - jbe 4f - - /* Bump the wakeup number. */ -3: addl $1, wakeup_seq-cond_futex(%ebx) - adcl $0, wakeup_seq-cond_futex+4(%ebx) - addl $1, (%ebx) - - /* Wake up one thread. */ - pushl %esi - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%esi, 0) - pushl %ebp - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%ebp, 0) - -#if FUTEX_PRIVATE_FLAG > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex-cond_futex(%ebx) - sete %cl - je 8f - - movl dep_mutex-cond_futex(%ebx), %edx - /* Requeue to a non-robust PI mutex if the PI bit is set and - the robust bit is not set. */ - movl MUTEX_KIND(%edx), %eax - andl $(ROBUST_BIT|PI_BIT), %eax - cmpl $PI_BIT, %eax - je 9f - -8: subl $1, %ecx -#ifdef __ASSUME_PRIVATE_FUTEX - andl $FUTEX_PRIVATE_FLAG, %ecx -#else - andl %gs:PRIVATE_FUTEX, %ecx -#endif - addl $FUTEX_WAKE_OP, %ecx - movl $SYS_futex, %eax - movl $1, %edx - movl $1, %esi - movl $FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, %ebp - /* FIXME: Until Ingo fixes 4G/4G vDSO, 6 arg syscalls are broken for - sysenter. - ENTER_KERNEL */ - int $0x80 - popl %ebp - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebp) - popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) - - /* For any kind of error, we try again with WAKE. - The general test also covers running on old kernels. */ - cmpl $-4095, %eax - jae 7f - -6: xorl %eax, %eax - popl %edi - cfi_adjust_cfa_offset(-4) - cfi_restore(%edi) - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - ret - - cfi_restore_state - -9: movl $(FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx - movl $SYS_futex, %eax - movl $1, %edx - xorl %esi, %esi - movl dep_mutex-cond_futex(%ebx), %edi - movl (%ebx), %ebp - /* FIXME: Until Ingo fixes 4G/4G vDSO, 6 arg syscalls are broken for - sysenter. - ENTER_KERNEL */ - int $0x80 - popl %ebp - popl %esi - - leal -cond_futex(%ebx), %edi - - /* For any kind of error, we try again with WAKE. - The general test also covers running on old kernels. */ - cmpl $-4095, %eax - jb 4f - -7: -#ifdef __ASSUME_PRIVATE_FUTEX - andl $FUTEX_PRIVATE_FLAG, %ecx -#else - andl %gs:PRIVATE_FUTEX, %ecx -#endif - orl $FUTEX_WAKE, %ecx - - xorl $(FUTEX_WAKE ^ FUTEX_WAKE_OP), %ecx - movl $SYS_futex, %eax - /* %edx should be 1 already from $FUTEX_WAKE_OP syscall. - movl $1, %edx */ - ENTER_KERNEL - - /* Unlock. Note that at this point %edi always points to - cond_lock. */ -4: LOCK - subl $1, (%edi) - je 6b - - /* Unlock in loop requires wakeup. */ -5: movl %edi, %eax -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex-cond_futex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_unlock_wake - jmp 6b - - /* Initial locking failed. */ -1: -#if cond_lock == 0 - movl %edi, %edx -#else - leal cond_lock(%edi), %edx -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%edi) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_lock_wait - jmp 2b - - cfi_endproc - .size __pthread_cond_signal, .-__pthread_cond_signal -weak_alias(__pthread_cond_signal, pthread_cond_signal) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S deleted file mode 100644 index fd388f993..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S +++ /dev/null @@ -1,698 +0,0 @@ -/* Copyright (C) 2002-2004,2006-2007,2009,2010 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <lowlevellock.h> -#include <lowlevelcond.h> -#include <pthread-errnos.h> -#include <pthread-pi-defines.h> -#include <bits/kernel-features.h> -#include <tcb-offsets.h> - - - .text - -/* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec *abstime) */ - .globl __pthread_cond_timedwait - .type __pthread_cond_timedwait, @function - .protected __pthread_cond_timedwait - .align 16 -__pthread_cond_timedwait: -.LSTARTCODE: - cfi_startproc -#ifdef SHARED - cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect, - DW.ref.__gcc_personality_v0) - cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART) -#else - cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0) - cfi_lsda(DW_EH_PE_udata4, .LexceptSTART) -#endif - - pushl %ebp - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%ebp, 0) - pushl %edi - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%edi, 0) - pushl %esi - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%esi, 0) - pushl %ebx - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%ebx, 0) - - movl 20(%esp), %ebx - movl 28(%esp), %ebp - - cmpl $1000000000, 4(%ebp) - movl $EINVAL, %eax - jae 18f - - /* Get internal lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if cond_lock == 0 - cmpxchgl %edx, (%ebx) -#else - cmpxchgl %edx, cond_lock(%ebx) -#endif - jnz 1f - - /* Store the reference to the mutex. If there is already a - different value in there this is a bad user bug. */ -2: cmpl $-1, dep_mutex(%ebx) - movl 24(%esp), %eax - je 17f - movl %eax, dep_mutex(%ebx) - - /* Unlock the mutex. */ -17: xorl %edx, %edx - call __pthread_mutex_unlock_usercnt - - testl %eax, %eax - jne 16f - - addl $1, total_seq(%ebx) - adcl $0, total_seq+4(%ebx) - addl $1, cond_futex(%ebx) - addl $(1 << nwaiters_shift), cond_nwaiters(%ebx) - -#define FRAME_SIZE 32 - subl $FRAME_SIZE, %esp - cfi_adjust_cfa_offset(FRAME_SIZE) - cfi_remember_state - - /* Get and store current wakeup_seq value. */ - movl wakeup_seq(%ebx), %edi - movl wakeup_seq+4(%ebx), %edx - movl broadcast_seq(%ebx), %eax - movl %edi, 12(%esp) - movl %edx, 16(%esp) - movl %eax, 20(%esp) - - /* Reset the pi-requeued flag. */ -8: movl $0, 24(%esp) - /* Get the current time. */ - movl %ebx, %edx -#ifdef __NR_clock_gettime - /* Get the clock number. */ - movl cond_nwaiters(%ebx), %ebx - andl $((1 << nwaiters_shift) - 1), %ebx - /* Only clocks 0 and 1 are allowed so far. Both are handled in the - kernel. */ - leal 4(%esp), %ecx - movl $__NR_clock_gettime, %eax - ENTER_KERNEL -# ifndef __ASSUME_POSIX_TIMERS - cmpl $-ENOSYS, %eax - je 19f -# endif - movl %edx, %ebx - - /* Compute relative timeout. */ - movl (%ebp), %ecx - movl 4(%ebp), %edx - subl 4(%esp), %ecx - subl 8(%esp), %edx -#else - /* Get the current time. */ - leal 4(%esp), %ebx - xorl %ecx, %ecx - movl $__NR_gettimeofday, %eax - ENTER_KERNEL - movl %edx, %ebx - - /* Compute relative timeout. */ - movl 8(%esp), %eax - movl $1000, %edx - mul %edx /* Milli seconds to nano seconds. */ - movl (%ebp), %ecx - movl 4(%ebp), %edx - subl 4(%esp), %ecx - subl %eax, %edx -#endif - jns 12f - addl $1000000000, %edx - subl $1, %ecx -12: testl %ecx, %ecx - movl $-ETIMEDOUT, %esi - js 6f - - /* Store relative timeout. */ -21: movl %ecx, 4(%esp) - movl %edx, 8(%esp) - - movl cond_futex(%ebx), %edi - movl %edi, 28(%esp) - - /* Unlock. */ - LOCK -#if cond_lock == 0 - subl $1, (%ebx) -#else - subl $1, cond_lock(%ebx) -#endif - jne 3f - -.LcleanupSTART: -4: call __pthread_enable_asynccancel - movl %eax, (%esp) - -#if FUTEX_PRIVATE_FLAG > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - sete %cl - je 40f - - movl dep_mutex(%ebx), %edi - /* Requeue to a non-robust PI mutex if the PI bit is set and - the robust bit is not set. */ - movl MUTEX_KIND(%edi), %eax - andl $(ROBUST_BIT|PI_BIT), %eax - cmpl $PI_BIT, %eax - jne 40f - - movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx - /* The following only works like this because we only support - two clocks, represented using a single bit. */ - testl $1, cond_nwaiters(%ebx) - /* XXX Need to implement using sete instead of a jump. */ - jne 42f - orl $FUTEX_CLOCK_REALTIME, %ecx - - /* Requeue-PI uses absolute timeout */ -42: leal (%ebp), %esi - movl 28(%esp), %edx - addl $cond_futex, %ebx - movl $SYS_futex, %eax - ENTER_KERNEL - subl $cond_futex, %ebx - movl %eax, %esi - /* Set the pi-requeued flag only if the kernel has returned 0. The - kernel does not hold the mutex on ETIMEDOUT or any other error. */ - cmpl $0, %eax - sete 24(%esp) - je 41f - - /* Normal and PI futexes dont mix. Use normal futex functions only - if the kernel does not support the PI futex functions. */ - cmpl $-ENOSYS, %eax - jne 41f - xorl %ecx, %ecx - -40: subl $1, %ecx -#ifdef __ASSUME_PRIVATE_FUTEX - andl $FUTEX_PRIVATE_FLAG, %ecx -#else - andl %gs:PRIVATE_FUTEX, %ecx -#endif -#if FUTEX_WAIT != 0 - addl $FUTEX_WAIT, %ecx -#endif - leal 4(%esp), %esi - movl 28(%esp), %edx - addl $cond_futex, %ebx -.Ladd_cond_futex: - movl $SYS_futex, %eax - ENTER_KERNEL - subl $cond_futex, %ebx -.Lsub_cond_futex: - movl %eax, %esi - -41: movl (%esp), %eax - call __pthread_disable_asynccancel -.LcleanupEND: - - /* Lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if cond_lock == 0 - cmpxchgl %edx, (%ebx) -#else - cmpxchgl %edx, cond_lock(%ebx) -#endif - jnz 5f - -6: movl broadcast_seq(%ebx), %eax - cmpl 20(%esp), %eax - jne 23f - - movl woken_seq(%ebx), %eax - movl woken_seq+4(%ebx), %ecx - - movl wakeup_seq(%ebx), %edi - movl wakeup_seq+4(%ebx), %edx - - cmpl 16(%esp), %edx - jne 7f - cmpl 12(%esp), %edi - je 15f - -7: cmpl %ecx, %edx - jne 9f - cmp %eax, %edi - jne 9f - -15: cmpl $-ETIMEDOUT, %esi - jne 8b - - addl $1, wakeup_seq(%ebx) - adcl $0, wakeup_seq+4(%ebx) - addl $1, cond_futex(%ebx) - movl $ETIMEDOUT, %esi - jmp 14f - -23: xorl %esi, %esi - jmp 24f - -9: xorl %esi, %esi -14: addl $1, woken_seq(%ebx) - adcl $0, woken_seq+4(%ebx) - -24: subl $(1 << nwaiters_shift), cond_nwaiters(%ebx) - - /* Wake up a thread which wants to destroy the condvar object. */ - movl total_seq(%ebx), %eax - andl total_seq+4(%ebx), %eax - cmpl $0xffffffff, %eax - jne 25f - movl cond_nwaiters(%ebx), %eax - andl $~((1 << nwaiters_shift) - 1), %eax - jne 25f - - addl $cond_nwaiters, %ebx - movl $SYS_futex, %eax -#if FUTEX_PRIVATE_FLAG > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex-cond_nwaiters(%ebx) - sete %cl - subl $1, %ecx -#ifdef __ASSUME_PRIVATE_FUTEX - andl $FUTEX_PRIVATE_FLAG, %ecx -#else - andl %gs:PRIVATE_FUTEX, %ecx -#endif - addl $FUTEX_WAKE, %ecx - movl $1, %edx - ENTER_KERNEL - subl $cond_nwaiters, %ebx - -25: LOCK -#if cond_lock == 0 - subl $1, (%ebx) -#else - subl $1, cond_lock(%ebx) -#endif - jne 10f - -11: movl 24+FRAME_SIZE(%esp), %eax - /* With requeue_pi, the mutex lock is held in the kernel. */ - movl 24(%esp), %ecx - testl %ecx, %ecx - jnz 27f - - call __pthread_mutex_cond_lock -26: addl $FRAME_SIZE, %esp - cfi_adjust_cfa_offset(-FRAME_SIZE); - - /* We return the result of the mutex_lock operation if it failed. */ - testl %eax, %eax -#ifdef HAVE_CMOV - cmovel %esi, %eax -#else - jne 22f - movl %esi, %eax -22: -#endif - -18: popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) - popl %edi - cfi_adjust_cfa_offset(-4) - cfi_restore(%edi) - popl %ebp - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebp) - - ret - - cfi_restore_state - -27: call __pthread_mutex_cond_lock_adjust - xorl %eax, %eax - jmp 26b - - cfi_adjust_cfa_offset(-FRAME_SIZE); - /* Initial locking failed. */ -1: -#if cond_lock == 0 - movl %ebx, %edx -#else - leal cond_lock(%ebx), %edx -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_lock_wait - jmp 2b - - /* The initial unlocking of the mutex failed. */ -16: - LOCK -#if cond_lock == 0 - subl $1, (%ebx) -#else - subl $1, cond_lock(%ebx) -#endif - jne 18b - - movl %eax, %esi -#if cond_lock == 0 - movl %ebx, %eax -#else - leal cond_lock(%ebx), %eax -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_unlock_wake - - movl %esi, %eax - jmp 18b - - cfi_adjust_cfa_offset(FRAME_SIZE) - - /* Unlock in loop requires wakeup. */ -3: -#if cond_lock == 0 - movl %ebx, %eax -#else - leal cond_lock(%ebx), %eax -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_unlock_wake - jmp 4b - - /* Locking in loop failed. */ -5: -#if cond_lock == 0 - movl %ebx, %edx -#else - leal cond_lock(%ebx), %edx -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_lock_wait - jmp 6b - - /* Unlock after loop requires wakeup. */ -10: -#if cond_lock == 0 - movl %ebx, %eax -#else - leal cond_lock(%ebx), %eax -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_unlock_wake - jmp 11b - -#if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS - /* clock_gettime not available. */ -19: leal 4(%esp), %ebx - xorl %ecx, %ecx - movl $__NR_gettimeofday, %eax - ENTER_KERNEL - movl %edx, %ebx - - /* Compute relative timeout. */ - movl 8(%esp), %eax - movl $1000, %edx - mul %edx /* Milli seconds to nano seconds. */ - movl (%ebp), %ecx - movl 4(%ebp), %edx - subl 4(%esp), %ecx - subl %eax, %edx - jns 20f - addl $1000000000, %edx - subl $1, %ecx -20: testl %ecx, %ecx - movl $-ETIMEDOUT, %esi - js 6b - jmp 21b -#endif - .size __pthread_cond_timedwait, .-__pthread_cond_timedwait -weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait) - - - .type __condvar_tw_cleanup2, @function -__condvar_tw_cleanup2: - subl $cond_futex, %ebx - .size __condvar_tw_cleanup2, .-__condvar_tw_cleanup2 - .type __condvar_tw_cleanup, @function -__condvar_tw_cleanup: - movl %eax, %esi - - /* Get internal lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if cond_lock == 0 - cmpxchgl %edx, (%ebx) -#else - cmpxchgl %edx, cond_lock(%ebx) -#endif - jz 1f - -#if cond_lock == 0 - movl %ebx, %edx -#else - leal cond_lock(%ebx), %edx -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_lock_wait - -1: movl broadcast_seq(%ebx), %eax - cmpl 20(%esp), %eax - jne 3f - - /* We increment the wakeup_seq counter only if it is lower than - total_seq. If this is not the case the thread was woken and - then canceled. In this case we ignore the signal. */ - movl total_seq(%ebx), %eax - movl total_seq+4(%ebx), %edi - cmpl wakeup_seq+4(%ebx), %edi - jb 6f - ja 7f - cmpl wakeup_seq(%ebx), %eax - jbe 7f - -6: addl $1, wakeup_seq(%ebx) - adcl $0, wakeup_seq+4(%ebx) - addl $1, cond_futex(%ebx) - -7: addl $1, woken_seq(%ebx) - adcl $0, woken_seq+4(%ebx) - -3: subl $(1 << nwaiters_shift), cond_nwaiters(%ebx) - - /* Wake up a thread which wants to destroy the condvar object. */ - xorl %edi, %edi - movl total_seq(%ebx), %eax - andl total_seq+4(%ebx), %eax - cmpl $0xffffffff, %eax - jne 4f - movl cond_nwaiters(%ebx), %eax - andl $~((1 << nwaiters_shift) - 1), %eax - jne 4f - - addl $cond_nwaiters, %ebx - movl $SYS_futex, %eax -#if FUTEX_PRIVATE_FLAG > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex-cond_nwaiters(%ebx) - sete %cl - subl $1, %ecx -#ifdef __ASSUME_PRIVATE_FUTEX - andl $FUTEX_PRIVATE_FLAG, %ecx -#else - andl %gs:PRIVATE_FUTEX, %ecx -#endif - addl $FUTEX_WAKE, %ecx - movl $1, %edx - ENTER_KERNEL - subl $cond_nwaiters, %ebx - movl $1, %edi - -4: LOCK -#if cond_lock == 0 - subl $1, (%ebx) -#else - subl $1, cond_lock(%ebx) -#endif - je 2f - -#if cond_lock == 0 - movl %ebx, %eax -#else - leal cond_lock(%ebx), %eax -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_unlock_wake - - /* Wake up all waiters to make sure no signal gets lost. */ -2: testl %edi, %edi - jnz 5f - addl $cond_futex, %ebx -#if FUTEX_PRIVATE_FLAG > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex-cond_futex(%ebx) - sete %cl - subl $1, %ecx -#ifdef __ASSUME_PRIVATE_FUTEX - andl $FUTEX_PRIVATE_FLAG, %ecx -#else - andl %gs:PRIVATE_FUTEX, %ecx -#endif - addl $FUTEX_WAKE, %ecx - movl $SYS_futex, %eax - movl $0x7fffffff, %edx - ENTER_KERNEL - -5: movl 24+FRAME_SIZE(%esp), %eax - call __pthread_mutex_cond_lock - - movl %esi, (%esp) -.LcallUR: -#ifdef __PIC__ - call __i686.get_pc_thunk.bx - addl $_GLOBAL_OFFSET_TABLE_, %ebx -#endif - call _Unwind_Resume@PLT - hlt -.LENDCODE: - cfi_endproc - .size __condvar_tw_cleanup, .-__condvar_tw_cleanup - - - .section .gcc_except_table,"a",@progbits -.LexceptSTART: - .byte DW_EH_PE_omit # @LPStart format (omit) - .byte DW_EH_PE_omit # @TType format (omit) - .byte DW_EH_PE_sdata4 # call-site format - # DW_EH_PE_sdata4 - .uleb128 .Lcstend-.Lcstbegin -.Lcstbegin: - .long .LcleanupSTART-.LSTARTCODE - .long .Ladd_cond_futex-.LcleanupSTART - .long __condvar_tw_cleanup-.LSTARTCODE - .uleb128 0 - .long .Ladd_cond_futex-.LSTARTCODE - .long .Lsub_cond_futex-.Ladd_cond_futex - .long __condvar_tw_cleanup2-.LSTARTCODE - .uleb128 0 - .long .Lsub_cond_futex-.LSTARTCODE - .long .LcleanupEND-.Lsub_cond_futex - .long __condvar_tw_cleanup-.LSTARTCODE - .uleb128 0 - .long .LcallUR-.LSTARTCODE - .long .LENDCODE-.LcallUR - .long 0 - .uleb128 0 -.Lcstend: - - -#ifdef SHARED - .hidden DW.ref.__gcc_personality_v0 - .weak DW.ref.__gcc_personality_v0 - .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits - .align 4 - .type DW.ref.__gcc_personality_v0, @object - .size DW.ref.__gcc_personality_v0, 4 -DW.ref.__gcc_personality_v0: - .long __gcc_personality_v0 -#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S deleted file mode 100644 index 90f19800d..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S +++ /dev/null @@ -1,594 +0,0 @@ -/* Copyright (C) 2002-2004,2006-2007,2009,2010 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <lowlevellock.h> -#include <lowlevelcond.h> -#include <tcb-offsets.h> -#include <pthread-errnos.h> -#include <pthread-pi-defines.h> -#include <bits/kernel-features.h> - - - .text - -/* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */ - .globl __pthread_cond_wait - .type __pthread_cond_wait, @function - .protected __pthread_cond_wait - .align 16 -__pthread_cond_wait: -.LSTARTCODE: - cfi_startproc -#ifdef SHARED - cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect, - DW.ref.__gcc_personality_v0) - cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART) -#else - cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0) - cfi_lsda(DW_EH_PE_udata4, .LexceptSTART) -#endif - - pushl %ebp - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%ebp, 0) - pushl %edi - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%edi, 0) - pushl %esi - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%esi, 0) - pushl %ebx - cfi_adjust_cfa_offset(4) - cfi_rel_offset(%ebx, 0) - - xorl %esi, %esi - movl 20(%esp), %ebx - - /* Get internal lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if cond_lock == 0 - cmpxchgl %edx, (%ebx) -#else - cmpxchgl %edx, cond_lock(%ebx) -#endif - jnz 1f - - /* Store the reference to the mutex. If there is already a - different value in there this is a bad user bug. */ -2: cmpl $-1, dep_mutex(%ebx) - movl 24(%esp), %eax - je 15f - movl %eax, dep_mutex(%ebx) - - /* Unlock the mutex. */ -15: xorl %edx, %edx - call __pthread_mutex_unlock_usercnt - - testl %eax, %eax - jne 12f - - addl $1, total_seq(%ebx) - adcl $0, total_seq+4(%ebx) - addl $1, cond_futex(%ebx) - addl $(1 << nwaiters_shift), cond_nwaiters(%ebx) - -#define FRAME_SIZE 20 - subl $FRAME_SIZE, %esp - cfi_adjust_cfa_offset(FRAME_SIZE) - cfi_remember_state - - /* Get and store current wakeup_seq value. */ - movl wakeup_seq(%ebx), %edi - movl wakeup_seq+4(%ebx), %edx - movl broadcast_seq(%ebx), %eax - movl %edi, 4(%esp) - movl %edx, 8(%esp) - movl %eax, 12(%esp) - - /* Reset the pi-requeued flag. */ -8: movl $0, 16(%esp) - movl cond_futex(%ebx), %ebp - - /* Unlock. */ - LOCK -#if cond_lock == 0 - subl $1, (%ebx) -#else - subl $1, cond_lock(%ebx) -#endif - jne 3f - -.LcleanupSTART: -4: call __pthread_enable_asynccancel - movl %eax, (%esp) - - xorl %ecx, %ecx - cmpl $-1, dep_mutex(%ebx) - sete %cl - je 18f - - movl dep_mutex(%ebx), %edi - /* Requeue to a non-robust PI mutex if the PI bit is set and - the robust bit is not set. */ - movl MUTEX_KIND(%edi), %eax - andl $(ROBUST_BIT|PI_BIT), %eax - cmpl $PI_BIT, %eax - jne 18f - - movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx - movl %ebp, %edx - xorl %esi, %esi - addl $cond_futex, %ebx - movl $SYS_futex, %eax - ENTER_KERNEL - subl $cond_futex, %ebx - /* Set the pi-requeued flag only if the kernel has returned 0. The - kernel does not hold the mutex on error. */ - cmpl $0, %eax - sete 16(%esp) - je 19f - - /* Normal and PI futexes dont mix. Use normal futex functions only - if the kernel does not support the PI futex functions. */ - cmpl $-ENOSYS, %eax - jne 19f - xorl %ecx, %ecx - -18: subl $1, %ecx -#ifdef __ASSUME_PRIVATE_FUTEX - andl $FUTEX_PRIVATE_FLAG, %ecx -#else - andl %gs:PRIVATE_FUTEX, %ecx -#endif -#if FUTEX_WAIT != 0 - addl $FUTEX_WAIT, %ecx -#endif - movl %ebp, %edx - addl $cond_futex, %ebx -.Ladd_cond_futex: - movl $SYS_futex, %eax - ENTER_KERNEL - subl $cond_futex, %ebx -.Lsub_cond_futex: - -19: movl (%esp), %eax - call __pthread_disable_asynccancel -.LcleanupEND: - - /* Lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if cond_lock == 0 - cmpxchgl %edx, (%ebx) -#else - cmpxchgl %edx, cond_lock(%ebx) -#endif - jnz 5f - -6: movl broadcast_seq(%ebx), %eax - cmpl 12(%esp), %eax - jne 16f - - movl woken_seq(%ebx), %eax - movl woken_seq+4(%ebx), %ecx - - movl wakeup_seq(%ebx), %edi - movl wakeup_seq+4(%ebx), %edx - - cmpl 8(%esp), %edx - jne 7f - cmpl 4(%esp), %edi - je 8b - -7: cmpl %ecx, %edx - jne 9f - cmp %eax, %edi - je 8b - -9: addl $1, woken_seq(%ebx) - adcl $0, woken_seq+4(%ebx) - - /* Unlock */ -16: subl $(1 << nwaiters_shift), cond_nwaiters(%ebx) - - /* Wake up a thread which wants to destroy the condvar object. */ - movl total_seq(%ebx), %eax - andl total_seq+4(%ebx), %eax - cmpl $0xffffffff, %eax - jne 17f - movl cond_nwaiters(%ebx), %eax - andl $~((1 << nwaiters_shift) - 1), %eax - jne 17f - - addl $cond_nwaiters, %ebx - movl $SYS_futex, %eax -#if FUTEX_PRIVATE_FLAG > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex-cond_nwaiters(%ebx) - sete %cl - subl $1, %ecx -#ifdef __ASSUME_PRIVATE_FUTEX - andl $FUTEX_PRIVATE_FLAG, %ecx -#else - andl %gs:PRIVATE_FUTEX, %ecx -#endif - addl $FUTEX_WAKE, %ecx - movl $1, %edx - ENTER_KERNEL - subl $cond_nwaiters, %ebx - -17: LOCK -#if cond_lock == 0 - subl $1, (%ebx) -#else - subl $1, cond_lock(%ebx) -#endif - jne 10f - - /* With requeue_pi, the mutex lock is held in the kernel. */ -11: movl 24+FRAME_SIZE(%esp), %eax - movl 16(%esp), %ecx - testl %ecx, %ecx - jnz 21f - - call __pthread_mutex_cond_lock -20: addl $FRAME_SIZE, %esp - cfi_adjust_cfa_offset(-FRAME_SIZE); - -14: popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) - popl %edi - cfi_adjust_cfa_offset(-4) - cfi_restore(%edi) - popl %ebp - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebp) - - /* We return the result of the mutex_lock operation. */ - ret - - cfi_restore_state - -21: call __pthread_mutex_cond_lock_adjust - xorl %eax, %eax - jmp 20b - - cfi_adjust_cfa_offset(-FRAME_SIZE); - /* Initial locking failed. */ -1: -#if cond_lock == 0 - movl %ebx, %edx -#else - leal cond_lock(%ebx), %edx -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_lock_wait - jmp 2b - - /* The initial unlocking of the mutex failed. */ -12: - LOCK -#if cond_lock == 0 - subl $1, (%ebx) -#else - subl $1, cond_lock(%ebx) -#endif - jne 14b - - movl %eax, %esi -#if cond_lock == 0 - movl %ebx, %eax -#else - leal cond_lock(%ebx), %eax -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_unlock_wake - - movl %esi, %eax - jmp 14b - - cfi_adjust_cfa_offset(FRAME_SIZE) - - /* Unlock in loop requires wakeup. */ -3: -#if cond_lock == 0 - movl %ebx, %eax -#else - leal cond_lock(%ebx), %eax -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_unlock_wake - jmp 4b - - /* Locking in loop failed. */ -5: -#if cond_lock == 0 - movl %ebx, %edx -#else - leal cond_lock(%ebx), %edx -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_lock_wait - jmp 6b - - /* Unlock after loop requires wakeup. */ -10: -#if cond_lock == 0 - movl %ebx, %eax -#else - leal cond_lock(%ebx), %eax -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_unlock_wake - jmp 11b - .size __pthread_cond_wait, .-__pthread_cond_wait -weak_alias(__pthread_cond_wait, pthread_cond_wait) - - - .type __condvar_w_cleanup2, @function -__condvar_w_cleanup2: - subl $cond_futex, %ebx - .size __condvar_w_cleanup2, .-__condvar_w_cleanup2 -.LSbl4: - .type __condvar_w_cleanup, @function -__condvar_w_cleanup: - movl %eax, %esi - - /* Get internal lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if cond_lock == 0 - cmpxchgl %edx, (%ebx) -#else - cmpxchgl %edx, cond_lock(%ebx) -#endif - jz 1f - -#if cond_lock == 0 - movl %ebx, %edx -#else - leal cond_lock(%ebx), %edx -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_lock_wait - -1: movl broadcast_seq(%ebx), %eax - cmpl 12(%esp), %eax - jne 3f - - /* We increment the wakeup_seq counter only if it is lower than - total_seq. If this is not the case the thread was woken and - then canceled. In this case we ignore the signal. */ - movl total_seq(%ebx), %eax - movl total_seq+4(%ebx), %edi - cmpl wakeup_seq+4(%ebx), %edi - jb 6f - ja 7f - cmpl wakeup_seq(%ebx), %eax - jbe 7f - -6: addl $1, wakeup_seq(%ebx) - adcl $0, wakeup_seq+4(%ebx) - addl $1, cond_futex(%ebx) - -7: addl $1, woken_seq(%ebx) - adcl $0, woken_seq+4(%ebx) - -3: subl $(1 << nwaiters_shift), cond_nwaiters(%ebx) - - /* Wake up a thread which wants to destroy the condvar object. */ - xorl %edi, %edi - movl total_seq(%ebx), %eax - andl total_seq+4(%ebx), %eax - cmpl $0xffffffff, %eax - jne 4f - movl cond_nwaiters(%ebx), %eax - andl $~((1 << nwaiters_shift) - 1), %eax - jne 4f - - addl $cond_nwaiters, %ebx - movl $SYS_futex, %eax -#if FUTEX_PRIVATE_FLAG > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex-cond_nwaiters(%ebx) - sete %cl - subl $1, %ecx -#ifdef __ASSUME_PRIVATE_FUTEX - andl $FUTEX_PRIVATE_FLAG, %ecx -#else - andl %gs:PRIVATE_FUTEX, %ecx -#endif - addl $FUTEX_WAKE, %ecx - movl $1, %edx - ENTER_KERNEL - subl $cond_nwaiters, %ebx - movl $1, %edi - -4: LOCK -#if cond_lock == 0 - subl $1, (%ebx) -#else - subl $1, cond_lock(%ebx) -#endif - je 2f - -#if cond_lock == 0 - movl %ebx, %eax -#else - leal cond_lock(%ebx), %eax -#endif -#if (LLL_SHARED-LLL_PRIVATE) > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex(%ebx) - setne %cl - subl $1, %ecx - andl $(LLL_SHARED-LLL_PRIVATE), %ecx -#if LLL_PRIVATE != 0 - addl $LLL_PRIVATE, %ecx -#endif - call __lll_unlock_wake - - /* Wake up all waiters to make sure no signal gets lost. */ -2: testl %edi, %edi - jnz 5f - addl $cond_futex, %ebx -#if FUTEX_PRIVATE_FLAG > 255 - xorl %ecx, %ecx -#endif - cmpl $-1, dep_mutex-cond_futex(%ebx) - sete %cl - subl $1, %ecx -#ifdef __ASSUME_PRIVATE_FUTEX - andl $FUTEX_PRIVATE_FLAG, %ecx -#else - andl %gs:PRIVATE_FUTEX, %ecx -#endif - addl $FUTEX_WAKE, %ecx - movl $SYS_futex, %eax - movl $0x7fffffff, %edx - ENTER_KERNEL - -5: movl 24+FRAME_SIZE(%esp), %eax - call __pthread_mutex_cond_lock - - movl %esi, (%esp) -.LcallUR: -#ifdef __PIC__ - call __i686.get_pc_thunk.bx - addl $_GLOBAL_OFFSET_TABLE_, %ebx -#endif - call _Unwind_Resume@PLT - hlt -.LENDCODE: - cfi_endproc - .size __condvar_w_cleanup, .-__condvar_w_cleanup - - - .section .gcc_except_table,"a",@progbits -.LexceptSTART: - .byte DW_EH_PE_omit # @LPStart format (omit) - .byte DW_EH_PE_omit # @TType format (omit) - .byte DW_EH_PE_sdata4 # call-site format - # DW_EH_PE_sdata4 - .uleb128 .Lcstend-.Lcstbegin -.Lcstbegin: - .long .LcleanupSTART-.LSTARTCODE - .long .Ladd_cond_futex-.LcleanupSTART - .long __condvar_w_cleanup-.LSTARTCODE - .uleb128 0 - .long .Ladd_cond_futex-.LSTARTCODE - .long .Lsub_cond_futex-.Ladd_cond_futex - .long __condvar_w_cleanup2-.LSTARTCODE - .uleb128 0 - .long .Lsub_cond_futex-.LSTARTCODE - .long .LcleanupEND-.Lsub_cond_futex - .long __condvar_w_cleanup-.LSTARTCODE - .uleb128 0 - .long .LcallUR-.LSTARTCODE - .long .LENDCODE-.LcallUR - .long 0 - .uleb128 0 -.Lcstend: - -#ifdef __PIC__ - .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits - .globl __i686.get_pc_thunk.bx - .hidden __i686.get_pc_thunk.bx - .type __i686.get_pc_thunk.bx,@function -__i686.get_pc_thunk.bx: - movl (%esp), %ebx; - ret - .size __i686.get_pc_thunk.bx,.-__i686.get_pc_thunk.bx -#endif - -#ifdef SHARED - .hidden DW.ref.__gcc_personality_v0 - .weak DW.ref.__gcc_personality_v0 - .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits - .align 4 - .type DW.ref.__gcc_personality_v0, @object - .size DW.ref.__gcc_personality_v0, 4 -DW.ref.__gcc_personality_v0: - .long __gcc_personality_v0 -#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S deleted file mode 100644 index 23efa55da..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S +++ /dev/null @@ -1,194 +0,0 @@ -/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <lowlevellock.h> -#include <lowlevelrwlock.h> -#include <pthread-errnos.h> -#include <bits/kernel-features.h> -#include <tls.h> - - - .text - - .globl __pthread_rwlock_rdlock - .type __pthread_rwlock_rdlock,@function - .protected __pthread_rwlock_rdlock - .align 16 -__pthread_rwlock_rdlock: - cfi_startproc - pushl %esi - cfi_adjust_cfa_offset(4) - pushl %ebx - cfi_adjust_cfa_offset(4) - cfi_offset(%esi, -8) - cfi_offset(%ebx, -12) - - xorl %esi, %esi - movl 12(%esp), %ebx - - /* Get the lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if MUTEX == 0 - cmpxchgl %edx, (%ebx) -#else - cmpxchgl %edx, MUTEX(%ebx) -#endif - jnz 1f - -2: movl WRITER(%ebx), %eax - testl %eax, %eax - jne 14f - cmpl $0, WRITERS_QUEUED(%ebx) - je 5f - cmpb $0, FLAGS(%ebx) - je 5f - -3: addl $1, READERS_QUEUED(%ebx) - je 4f - - movl READERS_WAKEUP(%ebx), %edx - - LOCK -#if MUTEX == 0 - subl $1, (%ebx) -#else - subl $1, MUTEX(%ebx) -#endif - jne 10f - -11: -#ifdef __ASSUME_PRIVATE_FUTEX - movzbl PSHARED(%ebx), %ecx - xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx -#else - movzbl PSHARED(%ebx), %ecx -# if FUTEX_WAIT != 0 - orl $FUTEX_WAIT, %ecx -# endif - xorl %gs:PRIVATE_FUTEX, %ecx -#endif - addl $READERS_WAKEUP, %ebx - movl $SYS_futex, %eax - ENTER_KERNEL - - subl $READERS_WAKEUP, %ebx - - /* Reget the lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if MUTEX == 0 - cmpxchgl %edx, (%ebx) -#else - cmpxchgl %edx, MUTEX(%ebx) -#endif - jnz 12f - -13: subl $1, READERS_QUEUED(%ebx) - jmp 2b - -5: xorl %edx, %edx - addl $1, NR_READERS(%ebx) - je 8f -9: LOCK -#if MUTEX == 0 - subl $1, (%ebx) -#else - subl $1, MUTEX(%ebx) -#endif - jne 6f -7: - - movl %edx, %eax - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) - ret - - cfi_adjust_cfa_offset(8) - cfi_offset(%esi, -8) - cfi_offset(%ebx, -12) -1: -#if MUTEX == 0 - movl %ebx, %edx -#else - leal MUTEX(%ebx), %edx -#endif - movzbl PSHARED(%ebx), %ecx - call __lll_lock_wait - jmp 2b - -14: cmpl %gs:TID, %eax - jne 3b - /* Deadlock detected. */ - movl $EDEADLK, %edx - jmp 9b - -6: -#if MUTEX == 0 - movl %ebx, %eax -#else - leal MUTEX(%ebx), %eax -#endif - movzbl PSHARED(%ebx), %ecx - call __lll_unlock_wake - jmp 7b - - /* Overflow. */ -8: subl $1, NR_READERS(%ebx) - movl $EAGAIN, %edx - jmp 9b - - /* Overflow. */ -4: subl $1, READERS_QUEUED(%ebx) - movl $EAGAIN, %edx - jmp 9b - -10: -#if MUTEX == 0 - movl %ebx, %eax -#else - leal MUTEX(%ebx), %eax -#endif - movzbl PSHARED(%ebx), %ecx - call __lll_unlock_wake - jmp 11b - -12: -#if MUTEX == 0 - movl %ebx, %edx -#else - leal MUTEX(%ebx), %edx -#endif - movzbl PSHARED(%ebx), %ecx - call __lll_lock_wait - jmp 13b - cfi_endproc - .size __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock - - .globl pthread_rwlock_rdlock -pthread_rwlock_rdlock = __pthread_rwlock_rdlock - - .globl __pthread_rwlock_rdlock_internal -__pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S deleted file mode 100644 index 89baa00ec..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S +++ /dev/null @@ -1,244 +0,0 @@ -/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <lowlevellock.h> -#include <lowlevelrwlock.h> -#include <pthread-errnos.h> -#include <bits/kernel-features.h> -#include <tls.h> - - - .text - - .globl pthread_rwlock_timedrdlock - .type pthread_rwlock_timedrdlock,@function - .align 16 -pthread_rwlock_timedrdlock: - cfi_startproc - pushl %esi - cfi_adjust_cfa_offset(4) - pushl %edi - cfi_adjust_cfa_offset(4) - pushl %ebx - cfi_adjust_cfa_offset(4) - pushl %ebp - cfi_adjust_cfa_offset(4) - cfi_offset(%esi, -8) - cfi_offset(%edi, -12) - cfi_offset(%ebx, -16) - cfi_offset(%ebp, -20) - subl $8, %esp - cfi_adjust_cfa_offset(8) - - movl 28(%esp), %ebp - movl 32(%esp), %edi - - /* Get the lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if MUTEX == 0 - cmpxchgl %edx, (%ebp) -#else - cmpxchgl %edx, MUTEX(%ebp) -#endif - jnz 1f - -2: movl WRITER(%ebp), %eax - testl %eax, %eax - jne 14f - cmpl $0, WRITERS_QUEUED(%ebp) - je 5f - cmpb $0, FLAGS(%ebp) - je 5f - - /* Check the value of the timeout parameter. */ -3: cmpl $1000000000, 4(%edi) - jae 19f - - addl $1, READERS_QUEUED(%ebp) - je 4f - - movl READERS_WAKEUP(%ebp), %esi - - LOCK -#if MUTEX == 0 - subl $1, (%ebp) -#else - subl $1, MUTEX(%ebp) -#endif - jne 10f - - /* Get current time. */ -11: movl %esp, %ebx - xorl %ecx, %ecx - movl $__NR_gettimeofday, %eax - ENTER_KERNEL - - /* Compute relative timeout. */ - movl 4(%esp), %eax - movl $1000, %edx - mul %edx /* Milli seconds to nano seconds. */ - movl (%edi), %ecx - movl 4(%edi), %edx - subl (%esp), %ecx - subl %eax, %edx - jns 15f - addl $1000000000, %edx - subl $1, %ecx -15: testl %ecx, %ecx - js 16f /* Time is already up. */ - - /* Futex call. */ - movl %ecx, (%esp) /* Store relative timeout. */ - movl %edx, 4(%esp) - - movl %esi, %edx -#ifdef __ASSUME_PRIVATE_FUTEX - movzbl PSHARED(%ebp), %ecx - xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx -#else - movzbl PSHARED(%ebp), %ecx -# if FUTEX_WAIT != 0 - orl $FUTEX_WAIT, %ecx -# endif - xorl %gs:PRIVATE_FUTEX, %ecx -#endif - movl %esp, %esi - leal READERS_WAKEUP(%ebp), %ebx - movl $SYS_futex, %eax - ENTER_KERNEL - movl %eax, %esi -17: - - /* Reget the lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if MUTEX == 0 - cmpxchgl %edx, (%ebp) -#else - cmpxchgl %edx, MUTEX(%ebp) -#endif - jnz 12f - -13: subl $1, READERS_QUEUED(%ebp) - cmpl $-ETIMEDOUT, %esi - jne 2b - -18: movl $ETIMEDOUT, %edx - jmp 9f - - -5: xorl %edx, %edx - addl $1, NR_READERS(%ebp) - je 8f -9: LOCK -#if MUTEX == 0 - subl $1, (%ebp) -#else - subl $1, MUTEX(%ebp) -#endif - jne 6f - -7: movl %edx, %eax - - addl $8, %esp - cfi_adjust_cfa_offset(-8) - popl %ebp - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebp) - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - popl %edi - cfi_adjust_cfa_offset(-4) - cfi_restore(%edi) - popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) - ret - - cfi_adjust_cfa_offset(24) - cfi_offset(%esi, -8) - cfi_offset(%edi, -12) - cfi_offset(%ebx, -16) - cfi_offset(%ebp, -20) -1: -#if MUTEX == 0 - movl %ebp, %edx -#else - leal MUTEX(%ebp), %edx -#endif - movzbl PSHARED(%ebp), %ecx - call __lll_lock_wait - jmp 2b - -14: cmpl %gs:TID, %eax - jne 3b - movl $EDEADLK, %edx - jmp 9b - -6: -#if MUTEX == 0 - movl %ebp, %eax -#else - leal MUTEX(%ebp), %eax -#endif - movzbl PSHARED(%ebp), %ecx - call __lll_unlock_wake - jmp 7b - - /* Overflow. */ -8: subl $1, NR_READERS(%ebp) - movl $EAGAIN, %edx - jmp 9b - - /* Overflow. */ -4: subl $1, READERS_QUEUED(%ebp) - movl $EAGAIN, %edx - jmp 9b - -10: -#if MUTEX == 0 - movl %ebp, %eax -#else - leal MUTEX(%ebp), %eax -#endif - movzbl PSHARED(%ebp), %ecx - call __lll_unlock_wake - jmp 11b - -12: -#if MUTEX == 0 - movl %ebp, %edx -#else - leal MUTEX(%ebp), %edx -#endif - movzbl PSHARED(%ebp), %ecx - call __lll_lock_wait - jmp 13b - -16: movl $-ETIMEDOUT, %esi - jmp 17b - -19: movl $EINVAL, %edx - jmp 9b - cfi_endproc - .size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S deleted file mode 100644 index 146a8a881..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S +++ /dev/null @@ -1,237 +0,0 @@ -/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <lowlevellock.h> -#include <lowlevelrwlock.h> -#include <pthread-errnos.h> -#include <bits/kernel-features.h> -#include <tls.h> - - - .text - - .globl pthread_rwlock_timedwrlock - .type pthread_rwlock_timedwrlock,@function - .align 16 -pthread_rwlock_timedwrlock: - cfi_startproc - pushl %esi - cfi_adjust_cfa_offset(4) - pushl %edi - cfi_adjust_cfa_offset(4) - pushl %ebx - cfi_adjust_cfa_offset(4) - pushl %ebp - cfi_adjust_cfa_offset(4) - cfi_offset(%esi, -8) - cfi_offset(%edi, -12) - cfi_offset(%ebx, -16) - cfi_offset(%ebp, -20) - subl $8, %esp - cfi_adjust_cfa_offset(8) - - movl 28(%esp), %ebp - movl 32(%esp), %edi - - /* Get the lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if MUTEX == 0 - cmpxchgl %edx, (%ebp) -#else - cmpxchgl %edx, MUTEX(%ebp) -#endif - jnz 1f - -2: movl WRITER(%ebp), %eax - testl %eax, %eax - jne 14f - cmpl $0, NR_READERS(%ebp) - je 5f - - /* Check the value of the timeout parameter. */ -3: cmpl $1000000000, 4(%edi) - jae 19f - - addl $1, WRITERS_QUEUED(%ebp) - je 4f - - movl WRITERS_WAKEUP(%ebp), %esi - - LOCK -#if MUTEX == 0 - subl $1, (%ebp) -#else - subl $1, MUTEX(%ebp) -#endif - jne 10f - - /* Get current time. */ -11: movl %esp, %ebx - xorl %ecx, %ecx - movl $__NR_gettimeofday, %eax - ENTER_KERNEL - - /* Compute relative timeout. */ - movl 4(%esp), %eax - movl $1000, %edx - mul %edx /* Milli seconds to nano seconds. */ - movl (%edi), %ecx - movl 4(%edi), %edx - subl (%esp), %ecx - subl %eax, %edx - jns 15f - addl $1000000000, %edx - subl $1, %ecx -15: testl %ecx, %ecx - js 16f /* Time is already up. */ - - /* Futex call. */ - movl %ecx, (%esp) /* Store relative timeout. */ - movl %edx, 4(%esp) - - movl %esi, %edx -#ifdef __ASSUME_PRIVATE_FUTEX - movzbl PSHARED(%ebp), %ecx - xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx -#else - movzbl PSHARED(%ebp), %ecx -# if FUTEX_WAIT != 0 - orl $FUTEX_WAIT, %ecx -# endif - xorl %gs:PRIVATE_FUTEX, %ecx -#endif - movl %esp, %esi - leal WRITERS_WAKEUP(%ebp), %ebx - movl $SYS_futex, %eax - ENTER_KERNEL - movl %eax, %esi -17: - - /* Reget the lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if MUTEX == 0 - cmpxchgl %edx, (%ebp) -#else - cmpxchgl %edx, MUTEX(%ebp) -#endif - jnz 12f - -13: subl $1, WRITERS_QUEUED(%ebp) - cmpl $-ETIMEDOUT, %esi - jne 2b - -18: movl $ETIMEDOUT, %edx - jmp 9f - - -5: xorl %edx, %edx - movl %gs:TID, %eax - movl %eax, WRITER(%ebp) -9: LOCK -#if MUTEX == 0 - subl $1, (%ebp) -#else - subl $1, MUTEX(%ebp) -#endif - jne 6f - -7: movl %edx, %eax - - addl $8, %esp - cfi_adjust_cfa_offset(-8) - popl %ebp - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebp) - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - popl %edi - cfi_adjust_cfa_offset(-4) - cfi_restore(%edi) - popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) - ret - - cfi_adjust_cfa_offset(24) - cfi_offset(%esi, -8) - cfi_offset(%edi, -12) - cfi_offset(%ebx, -16) - cfi_offset(%ebp, -20) -1: -#if MUTEX == 0 - movl %ebp, %edx -#else - leal MUTEX(%ebp), %edx -#endif - movzbl PSHARED(%ebp), %ecx - call __lll_lock_wait - jmp 2b - -14: cmpl %gs:TID, %eax - jne 3b -20: movl $EDEADLK, %edx - jmp 9b - -6: -#if MUTEX == 0 - movl %ebp, %eax -#else - leal MUTEX(%ebp), %eax -#endif - movzbl PSHARED(%ebp), %ecx - call __lll_unlock_wake - jmp 7b - - /* Overflow. */ -4: subl $1, WRITERS_QUEUED(%ebp) - movl $EAGAIN, %edx - jmp 9b - -10: -#if MUTEX == 0 - movl %ebp, %eax -#else - leal MUTEX(%ebp), %eax -#endif - movzbl PSHARED(%ebp), %ecx - call __lll_unlock_wake - jmp 11b - -12: -#if MUTEX == 0 - movl %ebp, %edx -#else - leal MUTEX(%ebp), %edx -#endif - movzbl PSHARED(%ebp), %ecx - call __lll_lock_wait - jmp 13b - -16: movl $-ETIMEDOUT, %esi - jmp 17b - -19: movl $EINVAL, %edx - jmp 9b - cfi_endproc - .size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S deleted file mode 100644 index ec3314770..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S +++ /dev/null @@ -1,156 +0,0 @@ -/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <lowlevellock.h> -#include <lowlevelrwlock.h> -#include <bits/kernel-features.h> -#include <tls.h> - - - .text - - .globl __pthread_rwlock_unlock - .type __pthread_rwlock_unlock,@function - .protected __pthread_rwlock_unlock - .align 16 -__pthread_rwlock_unlock: - cfi_startproc - pushl %ebx - cfi_adjust_cfa_offset(4) - pushl %edi - cfi_adjust_cfa_offset(4) - cfi_offset(%ebx, -8) - cfi_offset(%edi, -12) - - movl 12(%esp), %edi - - /* Get the lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if MUTEX == 0 - cmpxchgl %edx, (%edi) -#else - cmpxchgl %edx, MUTEX(%edi) -#endif - jnz 1f - -2: cmpl $0, WRITER(%edi) - jne 5f - subl $1, NR_READERS(%edi) - jnz 6f - -5: movl $0, WRITER(%edi) - - movl $1, %edx - leal WRITERS_WAKEUP(%edi), %ebx - cmpl $0, WRITERS_QUEUED(%edi) - jne 0f - - /* If also no readers waiting nothing to do. */ - cmpl $0, READERS_QUEUED(%edi) - je 6f - - movl $0x7fffffff, %edx - leal READERS_WAKEUP(%edi), %ebx - -0: addl $1, (%ebx) - LOCK -#if MUTEX == 0 - subl $1, (%edi) -#else - subl $1, MUTEX(%edi) -#endif - jne 7f - -8: -#ifdef __ASSUME_PRIVATE_FUTEX - movzbl PSHARED(%edi), %ecx - xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %ecx -#else - movzbl PSHARED(%edi), %ecx - orl $FUTEX_WAKE, %ecx - xorl %gs:PRIVATE_FUTEX, %ecx -#endif - movl $SYS_futex, %eax - ENTER_KERNEL - - xorl %eax, %eax - popl %edi - cfi_adjust_cfa_offset(-4) - cfi_restore(%edi) - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - ret - - cfi_adjust_cfa_offset(8) - cfi_offset(%ebx, -8) - cfi_offset(%edi, -12) - .align 16 -6: LOCK -#if MUTEX == 0 - subl $1, (%edi) -#else - subl $1, MUTEX(%edi) -#endif - jne 3f - -4: xorl %eax, %eax - popl %edi - popl %ebx - ret - -1: -#if MUTEX == 0 - movl %edi, %edx -#else - leal MUTEX(%edi), %edx -#endif - movzbl PSHARED(%edi), %ecx - call __lll_lock_wait - jmp 2b - -3: -#if MUTEX == 0 - movl %edi, %eax -#else - leal MUTEX(%edi), %eax -#endif - movzbl PSHARED(%edi), %ecx - call __lll_unlock_wake - jmp 4b - -7: -#if MUTEX == 0 - movl %edi, %eax -#else - leal MUTEX(%edi), %eax -#endif - movzbl PSHARED(%edi), %ecx - call __lll_unlock_wake - jmp 8b - cfi_endproc - .size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock - - .globl pthread_rwlock_unlock -pthread_rwlock_unlock = __pthread_rwlock_unlock - - .globl __pthread_rwlock_unlock_internal -__pthread_rwlock_unlock_internal = __pthread_rwlock_unlock diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S deleted file mode 100644 index c0fc69119..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S +++ /dev/null @@ -1,185 +0,0 @@ -/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <lowlevellock.h> -#include <lowlevelrwlock.h> -#include <pthread-errnos.h> -#include <bits/kernel-features.h> -#include <tls.h> - - - .text - - .globl __pthread_rwlock_wrlock - .type __pthread_rwlock_wrlock,@function - .protected __pthread_rwlock_wrlock - .align 16 -__pthread_rwlock_wrlock: - cfi_startproc - pushl %esi - cfi_adjust_cfa_offset(4) - pushl %ebx - cfi_adjust_cfa_offset(4) - cfi_offset(%esi, -8) - cfi_offset(%ebx, -12) - - xorl %esi, %esi - movl 12(%esp), %ebx - - /* Get the lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if MUTEX == 0 - cmpxchgl %edx, (%ebx) -#else - cmpxchgl %edx, MUTEX(%ebx) -#endif - jnz 1f - -2: movl WRITER(%ebx), %eax - testl %eax, %eax - jne 14f - cmpl $0, NR_READERS(%ebx) - je 5f - -3: addl $1, WRITERS_QUEUED(%ebx) - je 4f - - movl WRITERS_WAKEUP(%ebx), %edx - - LOCK -#if MUTEX == 0 - subl $1, (%ebx) -#else - subl $1, MUTEX(%ebx) -#endif - jne 10f - -11: -#ifdef __ASSUME_PRIVATE_FUTEX - movzbl PSHARED(%ebx), %ecx - xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx -#else - movzbl PSHARED(%ebx), %ecx -# if FUTEX_WAIT != 0 - orl $FUTEX_WAIT, %ecx -# endif - xorl %gs:PRIVATE_FUTEX, %ecx -#endif - addl $WRITERS_WAKEUP, %ebx - movl $SYS_futex, %eax - ENTER_KERNEL - - subl $WRITERS_WAKEUP, %ebx - - /* Reget the lock. */ - movl $1, %edx - xorl %eax, %eax - LOCK -#if MUTEX == 0 - cmpxchgl %edx, (%ebx) -#else - cmpxchgl %edx, MUTEX(%ebx) -#endif - jnz 12f - -13: subl $1, WRITERS_QUEUED(%ebx) - jmp 2b - -5: xorl %edx, %edx - movl %gs:TID, %eax - movl %eax, WRITER(%ebx) -9: LOCK -#if MUTEX == 0 - subl $1, (%ebx) -#else - subl $1, MUTEX(%ebx) -#endif - jne 6f -7: - - movl %edx, %eax - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - popl %esi - cfi_adjust_cfa_offset(-4) - cfi_restore(%esi) - ret - - cfi_adjust_cfa_offset(8) - cfi_offset(%esi, -8) - cfi_offset(%ebx, -12) -1: -#if MUTEX == 0 - movl %ebx, %edx -#else - leal MUTEX(%ebx), %edx -#endif - movzbl PSHARED(%ebx), %ecx - call __lll_lock_wait - jmp 2b - -14: cmpl %gs:TID , %eax - jne 3b - movl $EDEADLK, %edx - jmp 9b - -6: -#if MUTEX == 0 - movl %ebx, %eax -#else - leal MUTEX(%ebx), %eax -#endif - movzbl PSHARED(%ebx), %ecx - call __lll_unlock_wake - jmp 7b - -4: subl $1, WRITERS_QUEUED(%ebx) - movl $EAGAIN, %edx - jmp 9b - -10: -#if MUTEX == 0 - movl %ebx, %eax -#else - leal MUTEX(%ebx), %eax -#endif - movzbl PSHARED(%ebx), %ecx - call __lll_unlock_wake - jmp 11b - -12: -#if MUTEX == 0 - movl %ebx, %edx -#else - leal MUTEX(%ebx), %edx -#endif - movzbl PSHARED(%ebx), %ecx - call __lll_lock_wait - jmp 13b - cfi_endproc - .size __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock - - .globl pthread_rwlock_wrlock -pthread_rwlock_wrlock = __pthread_rwlock_wrlock - - .globl __pthread_rwlock_wrlock_internal -__pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S deleted file mode 100644 index 2d7394d84..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <pthread-errnos.h> -#include <structsem.h> -#include <lowlevellock.h> - - - .text - - .globl sem_post - .type sem_post,@function - .align 16 -sem_post: - cfi_startproc - pushl %ebx - cfi_adjust_cfa_offset(4) - cfi_offset(%ebx, -8) - - movl 8(%esp), %ebx - -#if VALUE == 0 - movl (%ebx), %eax -#else - movl VALUE(%ebx), %eax -#endif -0: cmpl $SEM_VALUE_MAX, %eax - je 3f - leal 1(%eax), %edx - LOCK -#if VALUE == 0 - cmpxchgl %edx, (%ebx) -#else - cmpxchgl %edx, VALUE(%ebx) -#endif - jnz 0b - - cmpl $0, NWAITERS(%ebx) - je 2f - - movl $FUTEX_WAKE, %ecx - orl PRIVATE(%ebx), %ecx - movl $1, %edx - movl $SYS_futex, %eax - ENTER_KERNEL - - testl %eax, %eax - js 1f - -2: xorl %eax, %eax - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - ret - - cfi_adjust_cfa_offset(4) - cfi_offset(%ebx, -8) -1: -#ifdef __PIC__ - call __x86.get_pc_thunk.bx -#else - movl $4f, %ebx -4: -#endif - addl $_GLOBAL_OFFSET_TABLE_, %ebx -#if USE___THREAD -# ifdef NO_TLS_DIRECT_SEG_REFS - movl errno@gotntpoff(%ebx), %edx - addl %gs:0, %edx - movl $EINVAL, (%edx) -# else - movl errno@gotntpoff(%ebx), %edx - movl $EINVAL, %gs:(%edx) -# endif -#else - call __errno_location@plt - movl $EINVAL, (%eax) -#endif - - orl $-1, %eax - popl %ebx - ret - -3: -#ifdef __PIC__ - call __x86.get_pc_thunk.bx -#else - movl $5f, %ebx -5: -#endif - addl $_GLOBAL_OFFSET_TABLE_, %ebx -#if USE___THREAD -# ifdef NO_TLS_DIRECT_SEG_REFS - movl errno@gotntpoff(%ebx), %edx - addl %gs:0, %edx - movl $EOVERFLOW, (%edx) -# else - movl errno@gotntpoff(%ebx), %edx - movl $EOVERFLOW, %gs:(%edx) -# endif -#else - call __errno_location@plt - movl $EOVERFLOW, (%eax) -#endif - - orl $-1, %eax - popl %ebx - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) - ret - cfi_endproc - .size sem_post,.-sem_post - -#ifdef __PIC__ - .section .gnu.linkonce.t.__x86.get_pc_thunk.bx,"ax",@progbits - .globl __x86.get_pc_thunk.bx - .hidden __x86.get_pc_thunk.bx - .type __x86.get_pc_thunk.bx,@function -__x86.get_pc_thunk.bx: - movl (%esp), %ebx; - ret - .size __x86.get_pc_thunk.bx,.-__x86.get_pc_thunk.bx -#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S deleted file mode 100644 index 6d6968100..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S +++ /dev/null @@ -1,328 +0,0 @@ -/* Copyright (C) 2002, 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <pthread-errnos.h> -#include <structsem.h> -#include <lowlevellock.h> - - -#if VALUE != 0 -# error "code needs to be rewritten for VALUE != 0" -#endif - - - .text - - .globl sem_timedwait - .type sem_timedwait,@function - .align 16 -sem_timedwait: -.LSTARTCODE: - movl 4(%esp), %ecx - - movl (%ecx), %eax -2: testl %eax, %eax - je 1f - - leal -1(%eax), %edx - LOCK - cmpxchgl %edx, (%ecx) - jne 2b - - xorl %eax, %eax - ret - - /* Check whether the timeout value is valid. */ -1: pushl %esi -.Lpush_esi: - pushl %edi -.Lpush_edi: - pushl %ebx -.Lpush_ebx: - subl $12, %esp -.Lsub_esp: - - movl 32(%esp), %edi - - /* Check for invalid nanosecond field. */ - cmpl $1000000000, 4(%edi) - movl $EINVAL, %esi - jae 6f - - LOCK - incl NWAITERS(%ecx) - -7: xorl %ecx, %ecx - movl %esp, %ebx - movl %ecx, %edx - movl $__NR_gettimeofday, %eax - ENTER_KERNEL - - /* Compute relative timeout. */ - movl 4(%esp), %eax - movl $1000, %edx - mul %edx /* Milli seconds to nano seconds. */ - movl (%edi), %ecx - movl 4(%edi), %edx - subl (%esp), %ecx - subl %eax, %edx - jns 5f - addl $1000000000, %edx - subl $1, %ecx -5: testl %ecx, %ecx - movl $ETIMEDOUT, %esi - js 6f /* Time is already up. */ - - movl %ecx, (%esp) /* Store relative timeout. */ - movl %edx, 4(%esp) - -.LcleanupSTART: - call __pthread_enable_asynccancel - movl %eax, 8(%esp) - - movl 28(%esp), %ebx /* Load semaphore address. */ -#if FUTEX_WAIT == 0 - movl PRIVATE(%ebx), %ecx -#else - movl $FUTEX_WAIT, %ecx - orl PRIVATE(%ebx), %ecx -#endif - movl %esp, %esi - xorl %edx, %edx - movl $SYS_futex, %eax - ENTER_KERNEL - movl %eax, %esi - - movl 8(%esp), %eax - call __pthread_disable_asynccancel -.LcleanupEND: - - testl %esi, %esi - je 9f - cmpl $-EWOULDBLOCK, %esi - jne 3f - -9: movl (%ebx), %eax -8: testl %eax, %eax - je 7b - - leal -1(%eax), %ecx - LOCK - cmpxchgl %ecx, (%ebx) - jne 8b - - xorl %eax, %eax - - LOCK - decl NWAITERS(%ebx) - -10: addl $12, %esp -.Ladd_esp: - popl %ebx -.Lpop_ebx: - popl %edi -.Lpop_edi: - popl %esi -.Lpop_esi: - ret - -.Lafter_ret: -3: negl %esi -6: -#ifdef __PIC__ - call __x86.get_pc_thunk.bx -#else - movl $4f, %ebx -4: -#endif - addl $_GLOBAL_OFFSET_TABLE_, %ebx -#if USE___THREAD -# ifdef NO_TLS_DIRECT_SEG_REFS - movl errno@gotntpoff(%ebx), %edx - addl %gs:0, %edx - movl %esi, (%edx) -# else - movl errno@gotntpoff(%ebx), %edx - movl %esi, %gs:(%edx) -# endif -#else - call __errno_location@plt - movl %esi, (%eax) -#endif - - movl 28(%esp), %ebx /* Load semaphore address. */ - orl $-1, %eax - jmp 10b - .size sem_timedwait,.-sem_timedwait - - - .type sem_wait_cleanup,@function -sem_wait_cleanup: - LOCK - decl NWAITERS(%ebx) - movl %eax, (%esp) -.LcallUR: - call _Unwind_Resume@PLT - hlt -.LENDCODE: - .size sem_wait_cleanup,.-sem_wait_cleanup - - - .section .gcc_except_table,"a",@progbits -.LexceptSTART: - .byte 0xff # @LPStart format (omit) - .byte 0xff # @TType format (omit) - .byte 0x01 # call-site format - # DW_EH_PE_uleb128 - .uleb128 .Lcstend-.Lcstbegin -.Lcstbegin: - .uleb128 .LcleanupSTART-.LSTARTCODE - .uleb128 .LcleanupEND-.LcleanupSTART - .uleb128 sem_wait_cleanup-.LSTARTCODE - .uleb128 0 - .uleb128 .LcallUR-.LSTARTCODE - .uleb128 .LENDCODE-.LcallUR - .uleb128 0 - .uleb128 0 -.Lcstend: - - - .section .eh_frame,"a",@progbits -.LSTARTFRAME: - .long .LENDCIE-.LSTARTCIE # Length of the CIE. -.LSTARTCIE: - .long 0 # CIE ID. - .byte 1 # Version number. -#ifdef SHARED - .string "zPLR" # NUL-terminated augmentation - # string. -#else - .string "zPL" # NUL-terminated augmentation - # string. -#endif - .uleb128 1 # Code alignment factor. - .sleb128 -4 # Data alignment factor. - .byte 8 # Return address register - # column. -#ifdef SHARED - .uleb128 7 # Augmentation value length. - .byte 0x9b # Personality: DW_EH_PE_pcrel - # + DW_EH_PE_sdata4 - # + DW_EH_PE_indirect - .long DW.ref.__gcc_personality_v0-. - .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel - # + DW_EH_PE_sdata4. - .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel - # + DW_EH_PE_sdata4. -#else - .uleb128 6 # Augmentation value length. - .byte 0x0 # Personality: absolute - .long __gcc_personality_v0 - .byte 0x0 # LSDA Encoding: absolute -#endif - .byte 0x0c # DW_CFA_def_cfa - .uleb128 4 - .uleb128 4 - .byte 0x88 # DW_CFA_offset, column 0x10 - .uleb128 1 - .align 4 -.LENDCIE: - - .long .LENDFDE-.LSTARTFDE # Length of the FDE. -.LSTARTFDE: - .long .LSTARTFDE-.LSTARTFRAME # CIE pointer. -#ifdef SHARED - .long .LSTARTCODE-. # PC-relative start address - # of the code. -#else - .long .LSTARTCODE # Start address of the code. -#endif - .long .LENDCODE-.LSTARTCODE # Length of the code. - .uleb128 4 # Augmentation size -#ifdef SHARED - .long .LexceptSTART-. -#else - .long .LexceptSTART -#endif - - .byte 4 # DW_CFA_advance_loc4 - .long .Lpush_esi-.LSTARTCODE - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 8 - .byte 0x86 # DW_CFA_offset %esi - .uleb128 2 - .byte 4 # DW_CFA_advance_loc4 - .long .Lpush_edi-.Lpush_esi - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 12 - .byte 0x87 # DW_CFA_offset %edi - .uleb128 3 - .byte 4 # DW_CFA_advance_loc4 - .long .Lpush_ebx-.Lpush_edi - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 16 - .byte 0x83 # DW_CFA_offset %ebx - .uleb128 4 - .byte 4 # DW_CFA_advance_loc4 - .long .Lsub_esp-.Lpush_ebx - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 28 - .byte 4 # DW_CFA_advance_loc4 - .long .Ladd_esp-.Lsub_esp - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 16 - .byte 4 # DW_CFA_advance_loc4 - .long .Lpop_ebx-.Ladd_esp - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 12 - .byte 0xc3 # DW_CFA_restore %ebx - .byte 4 # DW_CFA_advance_loc4 - .long .Lpop_edi-.Lpop_ebx - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 8 - .byte 0xc7 # DW_CFA_restore %edi - .byte 4 # DW_CFA_advance_loc4 - .long .Lpop_esi-.Lpop_edi - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 4 - .byte 0xc6 # DW_CFA_restore %esi - .byte 4 # DW_CFA_advance_loc4 - .long .Lafter_ret-.Lpop_esi - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 28 - .byte 0x86 # DW_CFA_offset %esi - .uleb128 2 - .byte 0x87 # DW_CFA_offset %edi - .uleb128 3 - .byte 0x83 # DW_CFA_offset %ebx - .uleb128 4 - .align 4 -.LENDFDE: - - -#ifdef SHARED - .hidden DW.ref.__gcc_personality_v0 - .weak DW.ref.__gcc_personality_v0 - .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits - .align 4 - .type DW.ref.__gcc_personality_v0, @object - .size DW.ref.__gcc_personality_v0, 4 -DW.ref.__gcc_personality_v0: - .long __gcc_personality_v0 -#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S deleted file mode 100644 index befa0c912..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <pthread-errnos.h> -#include <lowlevellock.h> - - .text - - .globl sem_trywait - .type sem_trywait,@function - .align 16 -sem_trywait: - movl 4(%esp), %ecx - - movl (%ecx), %eax -2: testl %eax, %eax - jz 1f - - leal -1(%eax), %edx - LOCK - cmpxchgl %edx, (%ecx) - jne 2b - xorl %eax, %eax - ret - -1: -#ifdef __PIC__ - call __x86.get_pc_thunk.cx -#else - movl $3f, %ecx -3: -#endif - addl $_GLOBAL_OFFSET_TABLE_, %ecx -#if USE___THREAD -# ifdef NO_TLS_DIRECT_SEG_REFS - movl errno@gotntpoff(%ecx), %edx - addl %gs:0, %edx - movl $EAGAIN, (%edx) -# else - movl errno@gotntpoff(%ecx), %edx - movl $EAGAIN, %gs:(%edx) -# endif -#else - call __errno_location@plt - movl $EAGAIN, (%eax) -#endif - orl $-1, %eax - ret - .size sem_trywait,.-sem_trywait - -#ifdef __PIC__ - .section .gnu.linkonce.t.__x86.get_pc_thunk.cx,"ax",@progbits - .globl __x86.get_pc_thunk.cx - .hidden __x86.get_pc_thunk.cx - .type __x86.get_pc_thunk.cx,@function -__x86.get_pc_thunk.cx: - movl (%esp), %ecx; - ret - .size __x86.get_pc_thunk.cx,.-__x86.get_pc_thunk.cx -#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S deleted file mode 100644 index 5f568976d..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S +++ /dev/null @@ -1,267 +0,0 @@ -/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <pthread-errnos.h> -#include <structsem.h> -#include <lowlevellock.h> - - -#if VALUE != 0 -# error "code needs to be rewritten for VALUE != 0" -#endif - - .text - - .globl sem_wait - .type sem_wait,@function - .align 16 -sem_wait: -.LSTARTCODE: - pushl %ebx -.Lpush_ebx: - pushl %esi -.Lpush_esi: - subl $4, %esp -.Lsub_esp: - - movl 16(%esp), %ebx - - movl (%ebx), %eax -2: testl %eax, %eax - je 1f - - leal -1(%eax), %edx - LOCK - cmpxchgl %edx, (%ebx) - jne 2b -7: xorl %eax, %eax - -9: movl 4(%esp), %esi - movl 8(%esp), %ebx - addl $12, %esp -.Ladd_esp: - ret - -.Lafter_ret: -1: LOCK - incl NWAITERS(%ebx) - -.LcleanupSTART: -6: call __pthread_enable_asynccancel - movl %eax, (%esp) - -#if FUTEX_WAIT == 0 - movl PRIVATE(%ebx), %ecx -#else - movl $FUTEX_WAIT, %ecx - orl PRIVATE(%ebx), %ecx -#endif - xorl %esi, %esi - xorl %edx, %edx - movl $SYS_futex, %eax - ENTER_KERNEL - movl %eax, %esi - - movl (%esp), %eax - call __pthread_disable_asynccancel -.LcleanupEND: - - testl %esi, %esi - je 3f - cmpl $-EWOULDBLOCK, %esi - jne 4f - -3: - movl (%ebx), %eax -5: testl %eax, %eax - je 6b - - leal -1(%eax), %edx - LOCK - cmpxchgl %edx, (%ebx) - jne 5b - - LOCK - decl NWAITERS(%ebx) - jmp 7b - -4: LOCK - decl NWAITERS(%ebx) - - negl %esi -#ifdef __PIC__ - call __x86.get_pc_thunk.bx -#else - movl $8f, %ebx -8: -#endif - addl $_GLOBAL_OFFSET_TABLE_, %ebx -#if USE___THREAD -# ifdef NO_TLS_DIRECT_SEG_REFS - movl errno@gotntpoff(%ebx), %edx - addl %gs:0, %edx - movl %esi, (%edx) -# else - movl errno@gotntpoff(%ebx), %edx - movl %esi, %gs:(%edx) -# endif -#else - call __errno_location@plt - movl %esi, (%eax) -#endif - orl $-1, %eax - - jmp 9b - .size sem_wait,.-sem_wait - - - .type sem_wait_cleanup,@function -sem_wait_cleanup: - LOCK - decl NWAITERS(%ebx) - movl %eax, (%esp) -.LcallUR: - call _Unwind_Resume@PLT - hlt -.LENDCODE: - .size sem_wait_cleanup,.-sem_wait_cleanup - - - .section .gcc_except_table,"a",@progbits -.LexceptSTART: - .byte 0xff # @LPStart format (omit) - .byte 0xff # @TType format (omit) - .byte 0x01 # call-site format - # DW_EH_PE_uleb128 - .uleb128 .Lcstend-.Lcstbegin -.Lcstbegin: - .uleb128 .LcleanupSTART-.LSTARTCODE - .uleb128 .LcleanupEND-.LcleanupSTART - .uleb128 sem_wait_cleanup-.LSTARTCODE - .uleb128 0 - .uleb128 .LcallUR-.LSTARTCODE - .uleb128 .LENDCODE-.LcallUR - .uleb128 0 - .uleb128 0 -.Lcstend: - - - .section .eh_frame,"a",@progbits -.LSTARTFRAME: - .long .LENDCIE-.LSTARTCIE # Length of the CIE. -.LSTARTCIE: - .long 0 # CIE ID. - .byte 1 # Version number. -#ifdef SHARED - .string "zPLR" # NUL-terminated augmentation - # string. -#else - .string "zPL" # NUL-terminated augmentation - # string. -#endif - .uleb128 1 # Code alignment factor. - .sleb128 -4 # Data alignment factor. - .byte 8 # Return address register - # column. -#ifdef SHARED - .uleb128 7 # Augmentation value length. - .byte 0x9b # Personality: DW_EH_PE_pcrel - # + DW_EH_PE_sdata4 - # + DW_EH_PE_indirect - .long DW.ref.__gcc_personality_v0-. - .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel - # + DW_EH_PE_sdata4. - .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel - # + DW_EH_PE_sdata4. -#else - .uleb128 6 # Augmentation value length. - .byte 0x0 # Personality: absolute - .long __gcc_personality_v0 - .byte 0x0 # LSDA Encoding: absolute -#endif - .byte 0x0c # DW_CFA_def_cfa - .uleb128 4 - .uleb128 4 - .byte 0x88 # DW_CFA_offset, column 0x10 - .uleb128 1 - .align 4 -.LENDCIE: - - .long .LENDFDE-.LSTARTFDE # Length of the FDE. -.LSTARTFDE: - .long .LSTARTFDE-.LSTARTFRAME # CIE pointer. -#ifdef SHARED - .long .LSTARTCODE-. # PC-relative start address - # of the code. -#else - .long .LSTARTCODE # Start address of the code. -#endif - .long .LENDCODE-.LSTARTCODE # Length of the code. - .uleb128 4 # Augmentation size -#ifdef SHARED - .long .LexceptSTART-. -#else - .long .LexceptSTART -#endif - - .byte 4 # DW_CFA_advance_loc4 - .long .Lpush_ebx-.LSTARTCODE - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 8 - .byte 0x83 # DW_CFA_offset %ebx - .uleb128 2 - .byte 4 # DW_CFA_advance_loc4 - .long .Lpush_esi-.Lpush_ebx - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 12 - .byte 0x86 # DW_CFA_offset %esi - .uleb128 3 - .byte 4 # DW_CFA_advance_loc4 - .long .Lsub_esp-.Lpush_esi - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 16 - .byte 4 # DW_CFA_advance_loc4 - .long .Ladd_esp-.Lsub_esp - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 4 - .byte 0xc3 # DW_CFA_restore %ebx - .byte 0xc6 # DW_CFA_restore %esi - .byte 4 # DW_CFA_advance_loc4 - .long .Lafter_ret-.Ladd_esp - .byte 14 # DW_CFA_def_cfa_offset - .uleb128 16 - .byte 0x83 # DW_CFA_offset %ebx - .uleb128 2 - .byte 0x86 # DW_CFA_offset %esi - .uleb128 3 - .align 4 -.LENDFDE: - - -#ifdef SHARED - .hidden DW.ref.__gcc_personality_v0 - .weak DW.ref.__gcc_personality_v0 - .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits - .align 4 - .type DW.ref.__gcc_personality_v0, @object - .size DW.ref.__gcc_personality_v0, 4 -DW.ref.__gcc_personality_v0: - .long __gcc_personality_v0 -#endif - diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevellock.S deleted file mode 100644 index f567c1d6d..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevellock.S +++ /dev/null @@ -1 +0,0 @@ -#include "../i486/libc-lowlevellock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_broadcast.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_broadcast.S deleted file mode 100644 index 4d459716b..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_broadcast.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_cond_broadcast.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_signal.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_signal.S deleted file mode 100644 index 36634766c..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_signal.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_cond_signal.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_timedwait.S deleted file mode 100644 index 673d873de..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_timedwait.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_cond_timedwait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_rdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_rdlock.S deleted file mode 100644 index 688541a62..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_rdlock.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_rwlock_rdlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedrdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedrdlock.S deleted file mode 100644 index 353c28535..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedrdlock.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_rwlock_timedrdlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedwrlock.S deleted file mode 100644 index 515da0a4f..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedwrlock.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_rwlock_timedwrlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_unlock.S deleted file mode 100644 index 9d8acc4f3..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_unlock.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_rwlock_unlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_wrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_wrlock.S deleted file mode 100644 index 79ee12dde..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_wrlock.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_rwlock_wrlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S deleted file mode 100644 index ad941ce9a..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/sem_timedwait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S deleted file mode 100644 index 4044a723c..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/sem_trywait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S deleted file mode 100644 index 6f130d3d0..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/sem_wait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S deleted file mode 100644 index f567c1d6d..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S +++ /dev/null @@ -1 +0,0 @@ -#include "../i486/libc-lowlevellock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevellock.S deleted file mode 100644 index 59194c712..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevellock.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/lowlevellock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrobustlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrobustlock.S deleted file mode 100644 index 6103f2ee4..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrobustlock.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2002, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/lowlevelrobustlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_barrier_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_barrier_wait.S deleted file mode 100644 index d22c72467..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_barrier_wait.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_barrier_wait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_broadcast.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_broadcast.S deleted file mode 100644 index 4d459716b..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_broadcast.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_cond_broadcast.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_signal.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_signal.S deleted file mode 100644 index 36634766c..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_signal.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_cond_signal.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_timedwait.S deleted file mode 100644 index 3f67df1fc..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_timedwait.S +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#define HAVE_CMOV 1 -#include "../i486/pthread_cond_timedwait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_wait.S deleted file mode 100644 index d3e1549cd..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_wait.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_cond_wait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_rdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_rdlock.S deleted file mode 100644 index 688541a62..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_rdlock.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_rwlock_rdlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedrdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedrdlock.S deleted file mode 100644 index 353c28535..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedrdlock.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_rwlock_timedrdlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedwrlock.S deleted file mode 100644 index 515da0a4f..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedwrlock.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_rwlock_timedwrlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_unlock.S deleted file mode 100644 index 39f88ff68..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_unlock.S +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#define HAVE_CMOV 1 -#include "../i486/pthread_rwlock_unlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_wrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_wrlock.S deleted file mode 100644 index 79ee12dde..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_wrlock.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/pthread_rwlock_wrlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S deleted file mode 100644 index ad941ce9a..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/sem_timedwait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S deleted file mode 100644 index 4044a723c..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. - - 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 - <http://www.gnu.org/licenses/>. */ - -#include "../i486/sem_trywait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h deleted file mode 100644 index d27ef2b68..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +++ /dev/null @@ -1,584 +0,0 @@ -/* Copyright (C) 2002-2004, 2006-2008, 2009 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. - - 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 - <http://www.gnu.org/licenses/>. */ - -#ifndef _LOWLEVELLOCK_H -#define _LOWLEVELLOCK_H 1 - -#ifndef __ASSEMBLER__ -# include <time.h> -# include <sys/param.h> -# include <bits/pthreadtypes.h> -# include <bits/kernel-features.h> -# include <tcb-offsets.h> -# include <atomic.h> - -# ifndef LOCK_INSTR -# ifdef UP -# define LOCK_INSTR /* nothing */ -# else -# define LOCK_INSTR "lock;" -# endif -# endif -#else -# ifndef LOCK -# ifdef UP -# define LOCK -# else -# define LOCK lock -# endif -# endif -#endif - -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 -#define FUTEX_CMP_REQUEUE 4 -#define FUTEX_WAKE_OP 5 -#define FUTEX_LOCK_PI 6 -#define FUTEX_UNLOCK_PI 7 -#define FUTEX_TRYLOCK_PI 8 -#define FUTEX_WAIT_BITSET 9 -#define FUTEX_WAKE_BITSET 10 -#define FUTEX_WAIT_REQUEUE_PI 11 -#define FUTEX_CMP_REQUEUE_PI 12 -#define FUTEX_PRIVATE_FLAG 128 -#define FUTEX_CLOCK_REALTIME 256 - -#define FUTEX_BITSET_MATCH_ANY 0xffffffff - -#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1) - -/* Values for 'private' parameter of locking macros. Yes, the - definition seems to be backwards. But it is not. The bit will be - reversed before passing to the system call. */ -#define LLL_PRIVATE 0 -#define LLL_SHARED FUTEX_PRIVATE_FLAG - - -#if !defined NOT_IN_libc || defined IS_IN_rtld -/* In libc.so or ld.so all futexes are private. */ -# ifdef __ASSUME_PRIVATE_FUTEX -# define __lll_private_flag(fl, private) \ - ((fl) | FUTEX_PRIVATE_FLAG) -# else -# define __lll_private_flag(fl, private) \ - ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) -# endif -#else -# ifdef __ASSUME_PRIVATE_FUTEX -# define __lll_private_flag(fl, private) \ - (((fl) | FUTEX_PRIVATE_FLAG) ^ (private)) -# else -# define __lll_private_flag(fl, private) \ - (__builtin_constant_p (private) \ - ? ((private) == 0 \ - ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \ - : (fl)) \ - : ({ unsigned int __fl = ((private) ^ FUTEX_PRIVATE_FLAG); \ - __asm__ ("andl %%gs:%P1, %0" : "+r" (__fl) \ - : "i" (offsetof (struct pthread, header.private_futex))); \ - __fl | (fl); })) -# endif -#endif - -#ifndef __ASSEMBLER__ - -/* Initializer for compatibility lock. */ -#define LLL_LOCK_INITIALIZER (0) -#define LLL_LOCK_INITIALIZER_LOCKED (1) -#define LLL_LOCK_INITIALIZER_WAITERS (2) - - -#ifdef __PIC__ -# define LLL_EBX_LOAD "xchgl %2, %%ebx\n" -# define LLL_EBX_REG "D" -#else -# define LLL_EBX_LOAD -# define LLL_EBX_REG "b" -#endif - -#ifdef I386_USE_SYSENTER -# ifdef SHARED -# define LLL_ENTER_KERNEL "call *%%gs:%P6\n\t" -# else -# define LLL_ENTER_KERNEL "call *_dl_sysinfo\n\t" -# endif -#else -# define LLL_ENTER_KERNEL "int $0x80\n\t" -#endif - -/* Delay in spinlock loop. */ -#define BUSY_WAIT_NOP __asm__ ("rep; nop") - - -#define LLL_STUB_UNWIND_INFO_START \ - ".section .eh_frame,\"a\",@progbits\n" \ -"5:\t" ".long 7f-6f # Length of Common Information Entry\n" \ -"6:\t" ".long 0x0 # CIE Identifier Tag\n\t" \ - ".byte 0x1 # CIE Version\n\t" \ - ".ascii \"zR\\0\" # CIE Augmentation\n\t" \ - ".uleb128 0x1 # CIE Code Alignment Factor\n\t" \ - ".sleb128 -4 # CIE Data Alignment Factor\n\t" \ - ".byte 0x8 # CIE RA Column\n\t" \ - ".uleb128 0x1 # Augmentation size\n\t" \ - ".byte 0x1b # FDE Encoding (pcrel sdata4)\n\t" \ - ".byte 0xc # DW_CFA_def_cfa\n\t" \ - ".uleb128 0x4\n\t" \ - ".uleb128 0x0\n\t" \ - ".align 4\n" \ -"7:\t" ".long 17f-8f # FDE Length\n" \ -"8:\t" ".long 8b-5b # FDE CIE offset\n\t" \ - ".long 1b-. # FDE initial location\n\t" \ - ".long 4b-1b # FDE address range\n\t" \ - ".uleb128 0x0 # Augmentation size\n\t" \ - ".byte 0x16 # DW_CFA_val_expression\n\t" \ - ".uleb128 0x8\n\t" \ - ".uleb128 10f-9f\n" \ -"9:\t" ".byte 0x78 # DW_OP_breg8\n\t" \ - ".sleb128 3b-1b\n" -#define LLL_STUB_UNWIND_INFO_END \ - ".byte 0x16 # DW_CFA_val_expression\n\t" \ - ".uleb128 0x8\n\t" \ - ".uleb128 12f-11f\n" \ -"11:\t" ".byte 0x78 # DW_OP_breg8\n\t" \ - ".sleb128 3b-2b\n" \ -"12:\t" ".byte 0x40 + (3b-2b-1) # DW_CFA_advance_loc\n\t" \ - ".byte 0x16 # DW_CFA_val_expression\n\t" \ - ".uleb128 0x8\n\t" \ - ".uleb128 16f-13f\n" \ -"13:\t" ".byte 0x78 # DW_OP_breg8\n\t" \ - ".sleb128 15f-14f\n\t" \ - ".byte 0x0d # DW_OP_const4s\n" \ -"14:\t" ".4byte 3b-.\n\t" \ - ".byte 0x1c # DW_OP_minus\n\t" \ - ".byte 0x0d # DW_OP_const4s\n" \ -"15:\t" ".4byte 18f-.\n\t" \ - ".byte 0x22 # DW_OP_plus\n" \ -"16:\t" ".align 4\n" \ -"17:\t" ".previous\n" - -/* Unwind info for - 1: lea ..., ... - 2: call ... - 3: jmp 18f - 4: - snippet. */ -#define LLL_STUB_UNWIND_INFO_3 \ -LLL_STUB_UNWIND_INFO_START \ -"10:\t" ".byte 0x40 + (2b-1b) # DW_CFA_advance_loc\n\t" \ -LLL_STUB_UNWIND_INFO_END - -/* Unwind info for - 1: lea ..., ... - 0: movl ..., ... - 2: call ... - 3: jmp 18f - 4: - snippet. */ -#define LLL_STUB_UNWIND_INFO_4 \ -LLL_STUB_UNWIND_INFO_START \ -"10:\t" ".byte 0x40 + (0b-1b) # DW_CFA_advance_loc\n\t" \ - ".byte 0x16 # DW_CFA_val_expression\n\t" \ - ".uleb128 0x8\n\t" \ - ".uleb128 20f-19f\n" \ -"19:\t" ".byte 0x78 # DW_OP_breg8\n\t" \ - ".sleb128 3b-0b\n" \ -"20:\t" ".byte 0x40 + (2b-0b) # DW_CFA_advance_loc\n\t" \ -LLL_STUB_UNWIND_INFO_END - - -#define lll_futex_wait(futex, val, private) \ - lll_futex_timed_wait (futex, val, NULL, private) - - -#define lll_futex_timed_wait(futex, val, timeout, private) \ - ({ \ - int __status; \ - register __typeof (val) _val __asm__ ("edx") = (val); \ - __asm__ __volatile__ (LLL_EBX_LOAD \ - LLL_ENTER_KERNEL \ - LLL_EBX_LOAD \ - : "=a" (__status) \ - : "0" (SYS_futex), LLL_EBX_REG (futex), "S" (timeout), \ - "c" (__lll_private_flag (FUTEX_WAIT, private)), \ - "d" (_val), "i" (offsetof (tcbhead_t, sysinfo)) \ - : "memory"); \ - __status; \ - }) - - -#define lll_futex_wake(futex, nr, private) \ - do { \ - int __ignore; \ - register __typeof (nr) _nr __asm__ ("edx") = (nr); \ - __asm__ __volatile__ (LLL_EBX_LOAD \ - LLL_ENTER_KERNEL \ - LLL_EBX_LOAD \ - : "=a" (__ignore) \ - : "0" (SYS_futex), LLL_EBX_REG (futex), \ - "c" (__lll_private_flag (FUTEX_WAKE, private)), \ - "d" (_nr), \ - "i" (0) /* phony, to align next arg's number */, \ - "i" (offsetof (tcbhead_t, sysinfo))); \ - } while (0) - - -/* NB: in the lll_trylock macro we simply return the value in %eax - after the cmpxchg instruction. In case the operation succeded this - value is zero. In case the operation failed, the cmpxchg instruction - has loaded the current value of the memory work which is guaranteed - to be nonzero. */ -#if defined NOT_IN_libc || defined UP -# define __lll_trylock_asm LOCK_INSTR "cmpxchgl %2, %1" -#else -# define __lll_trylock_asm "cmpl $0, %%gs:%P5\n\t" \ - "je 0f\n\t" \ - "lock\n" \ - "0:\tcmpxchgl %2, %1" -#endif - -#define lll_trylock(futex) \ - ({ int ret; \ - __asm__ __volatile__ (__lll_trylock_asm \ - : "=a" (ret), "=m" (futex) \ - : "r" (LLL_LOCK_INITIALIZER_LOCKED), "m" (futex), \ - "0" (LLL_LOCK_INITIALIZER), \ - "i" (MULTIPLE_THREADS_OFFSET) \ - : "memory"); \ - ret; }) - -#define lll_robust_trylock(futex, id) \ - ({ int ret; \ - __asm__ __volatile__ (LOCK_INSTR "cmpxchgl %2, %1" \ - : "=a" (ret), "=m" (futex) \ - : "r" (id), "m" (futex), \ - "0" (LLL_LOCK_INITIALIZER) \ - : "memory"); \ - ret; }) - - -#define lll_cond_trylock(futex) \ - ({ int ret; \ - __asm__ __volatile__ (LOCK_INSTR "cmpxchgl %2, %1" \ - : "=a" (ret), "=m" (futex) \ - : "r" (LLL_LOCK_INITIALIZER_WAITERS), \ - "m" (futex), "0" (LLL_LOCK_INITIALIZER) \ - : "memory"); \ - ret; }) - -#if defined NOT_IN_libc || defined UP -# define __lll_lock_asm_start LOCK_INSTR "cmpxchgl %1, %2\n\t" -#else -# define __lll_lock_asm_start "cmpl $0, %%gs:%P6\n\t" \ - "je 0f\n\t" \ - "lock\n" \ - "0:\tcmpxchgl %1, %2\n\t" -#endif - -#define lll_lock(futex, private) \ - (void) \ - ({ int ignore1, ignore2; \ - if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \ - __asm__ __volatile__ (__lll_lock_asm_start \ - "jnz _L_lock_%=\n\t" \ - ".subsection 1\n\t" \ - ".type _L_lock_%=,@function\n" \ - "_L_lock_%=:\n" \ - "1:\tleal %2, %%ecx\n" \ - "2:\tcall __lll_lock_wait_private\n" \ - "3:\tjmp 18f\n" \ - "4:\t.size _L_lock_%=, 4b-1b\n\t" \ - ".previous\n" \ - LLL_STUB_UNWIND_INFO_3 \ - "18:" \ - : "=a" (ignore1), "=c" (ignore2), "=m" (futex) \ - : "0" (0), "1" (1), "m" (futex), \ - "i" (MULTIPLE_THREADS_OFFSET) \ - : "memory"); \ - else \ - { \ - int ignore3; \ - __asm__ __volatile__ (__lll_lock_asm_start \ - "jnz _L_lock_%=\n\t" \ - ".subsection 1\n\t" \ - ".type _L_lock_%=,@function\n" \ - "_L_lock_%=:\n" \ - "1:\tleal %2, %%edx\n" \ - "0:\tmovl %8, %%ecx\n" \ - "2:\tcall __lll_lock_wait\n" \ - "3:\tjmp 18f\n" \ - "4:\t.size _L_lock_%=, 4b-1b\n\t" \ - ".previous\n" \ - LLL_STUB_UNWIND_INFO_4 \ - "18:" \ - : "=a" (ignore1), "=c" (ignore2), \ - "=m" (futex), "=&d" (ignore3) \ - : "1" (1), "m" (futex), \ - "i" (MULTIPLE_THREADS_OFFSET), "0" (0), \ - "g" ((int) (private)) \ - : "memory"); \ - } \ - }) - -#define lll_robust_lock(futex, id, private) \ - ({ int __ret, ignore1, ignore2; \ - __asm__ __volatile__ (LOCK_INSTR "cmpxchgl %1, %2\n\t" \ - "jnz _L_robust_lock_%=\n\t" \ - ".subsection 1\n\t" \ - ".type _L_robust_lock_%=,@function\n" \ - "_L_robust_lock_%=:\n" \ - "1:\tleal %2, %%edx\n" \ - "0:\tmovl %7, %%ecx\n" \ - "2:\tcall __lll_robust_lock_wait\n" \ - "3:\tjmp 18f\n" \ - "4:\t.size _L_robust_lock_%=, 4b-1b\n\t" \ - ".previous\n" \ - LLL_STUB_UNWIND_INFO_4 \ - "18:" \ - : "=a" (__ret), "=c" (ignore1), "=m" (futex), \ - "=&d" (ignore2) \ - : "0" (0), "1" (id), "m" (futex), "g" ((int) (private))\ - : "memory"); \ - __ret; }) - - -/* Special version of lll_lock which causes the unlock function to - always wakeup waiters. */ -#define lll_cond_lock(futex, private) \ - (void) \ - ({ int ignore1, ignore2, ignore3; \ - __asm__ __volatile__ (LOCK_INSTR "cmpxchgl %1, %2\n\t" \ - "jnz _L_cond_lock_%=\n\t" \ - ".subsection 1\n\t" \ - ".type _L_cond_lock_%=,@function\n" \ - "_L_cond_lock_%=:\n" \ - "1:\tleal %2, %%edx\n" \ - "0:\tmovl %7, %%ecx\n" \ - "2:\tcall __lll_lock_wait\n" \ - "3:\tjmp 18f\n" \ - "4:\t.size _L_cond_lock_%=, 4b-1b\n\t" \ - ".previous\n" \ - LLL_STUB_UNWIND_INFO_4 \ - "18:" \ - : "=a" (ignore1), "=c" (ignore2), "=m" (futex), \ - "=&d" (ignore3) \ - : "0" (0), "1" (2), "m" (futex), "g" ((int) (private))\ - : "memory"); \ - }) - - -#define lll_robust_cond_lock(futex, id, private) \ - ({ int __ret, ignore1, ignore2; \ - __asm__ __volatile__ (LOCK_INSTR "cmpxchgl %1, %2\n\t" \ - "jnz _L_robust_cond_lock_%=\n\t" \ - ".subsection 1\n\t" \ - ".type _L_robust_cond_lock_%=,@function\n" \ - "_L_robust_cond_lock_%=:\n" \ - "1:\tleal %2, %%edx\n" \ - "0:\tmovl %7, %%ecx\n" \ - "2:\tcall __lll_robust_lock_wait\n" \ - "3:\tjmp 18f\n" \ - "4:\t.size _L_robust_cond_lock_%=, 4b-1b\n\t" \ - ".previous\n" \ - LLL_STUB_UNWIND_INFO_4 \ - "18:" \ - : "=a" (__ret), "=c" (ignore1), "=m" (futex), \ - "=&d" (ignore2) \ - : "0" (0), "1" (id | FUTEX_WAITERS), "m" (futex), \ - "g" ((int) (private)) \ - : "memory"); \ - __ret; }) - - -#define lll_timedlock(futex, timeout, private) \ - ({ int __ret, ignore1, ignore2, ignore3; \ - __asm__ __volatile__ (LOCK_INSTR "cmpxchgl %1, %3\n\t" \ - "jnz _L_timedlock_%=\n\t" \ - ".subsection 1\n\t" \ - ".type _L_timedlock_%=,@function\n" \ - "_L_timedlock_%=:\n" \ - "1:\tleal %3, %%ecx\n" \ - "0:\tmovl %8, %%edx\n" \ - "2:\tcall __lll_timedlock_wait\n" \ - "3:\tjmp 18f\n" \ - "4:\t.size _L_timedlock_%=, 4b-1b\n\t" \ - ".previous\n" \ - LLL_STUB_UNWIND_INFO_4 \ - "18:" \ - : "=a" (__ret), "=c" (ignore1), "=&d" (ignore2), \ - "=m" (futex), "=S" (ignore3) \ - : "0" (0), "1" (1), "m" (futex), "m" (timeout), \ - "4" ((int) (private)) \ - : "memory"); \ - __ret; }) - - -#define lll_robust_timedlock(futex, timeout, id, private) \ - ({ int __ret, ignore1, ignore2, ignore3; \ - __asm__ __volatile__ (LOCK_INSTR "cmpxchgl %1, %3\n\t" \ - "jnz _L_robust_timedlock_%=\n\t" \ - ".subsection 1\n\t" \ - ".type _L_robust_timedlock_%=,@function\n" \ - "_L_robust_timedlock_%=:\n" \ - "1:\tleal %3, %%ecx\n" \ - "0:\tmovl %8, %%edx\n" \ - "2:\tcall __lll_robust_timedlock_wait\n" \ - "3:\tjmp 18f\n" \ - "4:\t.size _L_robust_timedlock_%=, 4b-1b\n\t" \ - ".previous\n" \ - LLL_STUB_UNWIND_INFO_4 \ - "18:" \ - : "=a" (__ret), "=c" (ignore1), "=&d" (ignore2), \ - "=m" (futex), "=S" (ignore3) \ - : "0" (0), "1" (id), "m" (futex), "m" (timeout), \ - "4" ((int) (private)) \ - : "memory"); \ - __ret; }) - -#if defined NOT_IN_libc || defined UP -# define __lll_unlock_asm LOCK_INSTR "subl $1, %0\n\t" -#else -# define __lll_unlock_asm "cmpl $0, %%gs:%P3\n\t" \ - "je 0f\n\t" \ - "lock\n" \ - "0:\tsubl $1,%0\n\t" -#endif - -#define lll_unlock(futex, private) \ - (void) \ - ({ int ignore; \ - if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \ - __asm__ __volatile__ (__lll_unlock_asm \ - "jne _L_unlock_%=\n\t" \ - ".subsection 1\n\t" \ - ".type _L_unlock_%=,@function\n" \ - "_L_unlock_%=:\n" \ - "1:\tleal %0, %%eax\n" \ - "2:\tcall __lll_unlock_wake_private\n" \ - "3:\tjmp 18f\n" \ - "4:\t.size _L_unlock_%=, 4b-1b\n\t" \ - ".previous\n" \ - LLL_STUB_UNWIND_INFO_3 \ - "18:" \ - : "=m" (futex), "=&a" (ignore) \ - : "m" (futex), "i" (MULTIPLE_THREADS_OFFSET) \ - : "memory"); \ - else \ - { \ - int ignore2; \ - __asm__ __volatile__ (__lll_unlock_asm \ - "jne _L_unlock_%=\n\t" \ - ".subsection 1\n\t" \ - ".type _L_unlock_%=,@function\n" \ - "_L_unlock_%=:\n" \ - "1:\tleal %0, %%eax\n" \ - "0:\tmovl %5, %%ecx\n" \ - "2:\tcall __lll_unlock_wake\n" \ - "3:\tjmp 18f\n" \ - "4:\t.size _L_unlock_%=, 4b-1b\n\t" \ - ".previous\n" \ - LLL_STUB_UNWIND_INFO_4 \ - "18:" \ - : "=m" (futex), "=&a" (ignore), "=&c" (ignore2) \ - : "i" (MULTIPLE_THREADS_OFFSET), "m" (futex), \ - "g" ((int) (private)) \ - : "memory"); \ - } \ - }) - -#define lll_robust_unlock(futex, private) \ - (void) \ - ({ int ignore, ignore2; \ - __asm__ __volatile__ (LOCK_INSTR "andl %3, %0\n\t" \ - "jne _L_robust_unlock_%=\n\t" \ - ".subsection 1\n\t" \ - ".type _L_robust_unlock_%=,@function\n" \ - "_L_robust_unlock_%=:\n\t" \ - "1:\tleal %0, %%eax\n" \ - "0:\tmovl %5, %%ecx\n" \ - "2:\tcall __lll_unlock_wake\n" \ - "3:\tjmp 18f\n" \ - "4:\t.size _L_robust_unlock_%=, 4b-1b\n\t" \ - ".previous\n" \ - LLL_STUB_UNWIND_INFO_4 \ - "18:" \ - : "=m" (futex), "=&a" (ignore), "=&c" (ignore2) \ - : "i" (FUTEX_WAITERS), "m" (futex), \ - "g" ((int) (private)) \ - : "memory"); \ - }) - - -#define lll_robust_dead(futex, private) \ - (void) \ - ({ int __ignore; \ - register int _nr __asm__ ("edx") = 1; \ - __asm__ __volatile__ (LOCK_INSTR "orl %5, (%2)\n\t" \ - LLL_EBX_LOAD \ - LLL_ENTER_KERNEL \ - LLL_EBX_LOAD \ - : "=a" (__ignore) \ - : "0" (SYS_futex), LLL_EBX_REG (&(futex)), \ - "c" (__lll_private_flag (FUTEX_WAKE, private)), \ - "d" (_nr), "i" (FUTEX_OWNER_DIED), \ - "i" (offsetof (tcbhead_t, sysinfo))); \ - }) - -#define lll_islocked(futex) \ - (futex != LLL_LOCK_INITIALIZER) - -/* The kernel notifies a process with uses CLONE_CLEARTID via futex - wakeup when the clone terminates. The memory location contains the - thread ID while the clone is running and is reset to zero - afterwards. - - The macro parameter must not have any side effect. */ -#define lll_wait_tid(tid) \ - do { \ - int __ignore; \ - register __typeof (tid) _tid __asm__ ("edx") = (tid); \ - if (_tid != 0) \ - __asm__ __volatile__ (LLL_EBX_LOAD \ - "1:\tmovl %1, %%eax\n\t" \ - LLL_ENTER_KERNEL \ - "cmpl $0, (%%ebx)\n\t" \ - "jne 1b\n\t" \ - LLL_EBX_LOAD \ - : "=&a" (__ignore) \ - : "i" (SYS_futex), LLL_EBX_REG (&tid), "S" (0), \ - "c" (FUTEX_WAIT), "d" (_tid), \ - "i" (offsetof (tcbhead_t, sysinfo)) \ - : "memory"); \ - } while (0) - -extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime) - __attribute__ ((regparm (2))) attribute_hidden; -#define lll_timedwait_tid(tid, abstime) \ - ({ \ - int __ret = 0; \ - if (tid != 0) \ - { \ - if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) \ - __ret = EINVAL; \ - else \ - __ret = __lll_timedwait_tid (&tid, abstime); \ - } \ - __ret; }) - -#endif /* !__ASSEMBLER__ */ - -#endif /* lowlevellock.h */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_init.c b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_init.c deleted file mode 100644 index d36e5373d..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_init.c +++ /dev/null @@ -1 +0,0 @@ -#include <sysdeps/i386/pthread_spin_init.c> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_unlock.S deleted file mode 100644 index 8bae0fd31..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_unlock.S +++ /dev/null @@ -1 +0,0 @@ -#include <sysdeps/i386/pthread_spin_unlock.S> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h index 6ecc23e25..99025fdf3 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -17,17 +17,6 @@ #ifndef _LOWLEVELLOCK_H #define _LOWLEVELLOCK_H 1 -#include <time.h> -#include <sys/param.h> -#include <bits/pthreadtypes.h> -#include <atomic.h> -#include <sysdep.h> -#include <bits/kernel-features.h> - -#if defined(__UCLIBC_USE_TIME64__) -#include "internal/time64_helpers.h" -#endif - #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 #define FUTEX_REQUEUE 3 @@ -44,6 +33,19 @@ #define FUTEX_BITSET_MATCH_ANY 0xffffffff +#ifndef __ASSEMBLER__ + +#include <time.h> +#include <sys/param.h> +#include <bits/pthreadtypes.h> +#include <atomic.h> +#include <sysdep.h> +#include <bits/kernel-features.h> + +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + /* Values for 'private' parameter of locking macros. Yes, the definition seems to be backwards. But it is not. The bit will be reversed before passing to the system call. */ @@ -337,4 +339,6 @@ extern int __lll_timedwait_tid (int *, const struct timespec *) __res; \ }) +#endif /* __ASSEMBLER__ */ + #endif /* lowlevellock.h */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/m68k/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/m68k/bits/pthreadtypes.h index 2a90a0b90..d2f22caee 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/m68k/bits/pthreadtypes.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/m68k/bits/pthreadtypes.h @@ -39,7 +39,7 @@ typedef unsigned long int pthread_t; typedef union { char __size[__SIZEOF_PTHREAD_ATTR_T]; - long int __align; + long int __align __attribute__((__aligned__(4))); } pthread_attr_t; @@ -69,13 +69,13 @@ typedef union }; } __data; char __size[__SIZEOF_PTHREAD_MUTEX_T]; - long int __align; + long int __align __attribute__((__aligned__(4))); } pthread_mutex_t; typedef union { char __size[__SIZEOF_PTHREAD_MUTEXATTR_T]; - long int __align; + long int __align __attribute__((__aligned__(4))); } pthread_mutexattr_t; @@ -95,13 +95,13 @@ typedef union unsigned int __broadcast_seq; } __data; char __size[__SIZEOF_PTHREAD_COND_T]; - __extension__ long long int __align; + __extension__ long long int __align __attribute__((__aligned__(8))); } pthread_cond_t; typedef union { char __size[__SIZEOF_PTHREAD_CONDATTR_T]; - long int __align; + long int __align __attribute__((__aligned__(4))); } pthread_condattr_t; @@ -144,13 +144,13 @@ typedef union int __writer; } __data; char __size[__SIZEOF_PTHREAD_RWLOCK_T]; - long int __align; + long int __align __attribute__((__aligned__(4))); } pthread_rwlock_t; typedef union { char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T]; - long int __align; + long int __align __attribute__((__aligned__(4))); } pthread_rwlockattr_t; #endif @@ -165,13 +165,13 @@ typedef volatile int pthread_spinlock_t; typedef union { char __size[__SIZEOF_PTHREAD_BARRIER_T]; - long int __align; + long int __align __attribute__((__aligned__(4))); } pthread_barrier_t; typedef union { char __size[__SIZEOF_PTHREAD_BARRIERATTR_T]; - int __align; + int __align __attribute__((__aligned__(4))); } pthread_barrierattr_t; #endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h index bbdb0739c..6d7c4d70a 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h @@ -19,6 +19,7 @@ #include <sys/types.h> #include <sysdep.h> +#include <time.h> /* Uncancelable open. */ #if defined __NR_openat && !defined __NR_open @@ -104,6 +105,7 @@ extern int __openat64_nocancel (int fd, const char *fname, int oflag, # define nanosleep_not_cancel(requested_time, remaining) \ INLINE_SYSCALL (nanosleep, 2, requested_time, remaining) #else +extern int __nanosleep_nocancel (const struct timespec *requested_time, struct timespec *remaining); # define nanosleep_not_cancel(requested_time, remaining) \ __nanosleep_nocancel (requested_time, remaining) #endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c index 220df0c37..fccda6976 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c @@ -24,7 +24,7 @@ #include "kernel-posix-timers.h" -#ifdef __NR_timer_gettime +#if defined(__NR_timer_gettime) || defined(__NR_timer_gettime64) # ifndef __ASSUME_POSIX_TIMERS static int compat_timer_gettime (timer_t timerid, struct itimerspec *value); # define timer_gettime static compat_timer_gettime diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_routines.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_routines.c index 60f2a724c..8c828fbb1 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_routines.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_routines.c @@ -90,8 +90,13 @@ timer_helper_thread (void *arg) /* XXX The size argument hopefully will have to be changed to the real size of the user-level sigset_t. */ +#if defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__) + int result = INLINE_SYSCALL (rt_sigtimedwait_time64, 4, &ss, &si, NULL, + _NSIG / 8); +#else int result = INLINE_SYSCALL (rt_sigtimedwait, 4, &ss, &si, NULL, _NSIG / 8); +#endif LIBC_CANCEL_RESET (oldtype); diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c index 1cccf57cb..fca839d64 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -27,7 +27,7 @@ #include "internal/time64_helpers.h" #endif -#ifdef __NR_timer_settime +#if defined(__NR_timer_settime) || defined(__NR_timer_settime64) # ifndef __ASSUME_POSIX_TIMERS static int compat_timer_settime (timer_t timerid, int flags, const struct itimerspec *value, diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch index 6f1734871..a3719a3fb 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/Makefile.arch @@ -9,3 +9,5 @@ CFLAGS-OMIT-fork.c = -DNOT_IN_libc -DIS_IN_libpthread ASFLAGS-syscall.S = -D_LIBC_REENTRANT ASFLAGS-mmap.S = -D_LIBC_REENTRANT + +ASFLAGS += -DUSE___THREAD diff --git a/libpthread/nptl/sysdeps/x86_64/dl-tls.h b/libpthread/nptl/sysdeps/x86_64/dl-tls.h index d6c338cda..5cac55f33 100644 --- a/libpthread/nptl/sysdeps/x86_64/dl-tls.h +++ b/libpthread/nptl/sysdeps/x86_64/dl-tls.h @@ -26,3 +26,6 @@ typedef struct extern void *__tls_get_addr (tls_index *ti); + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/libpthread/nptl/sysdeps/xtensa/dl-tls.h b/libpthread/nptl/sysdeps/xtensa/dl-tls.h index adc02d74a..dfc91753e 100644 --- a/libpthread/nptl/sysdeps/xtensa/dl-tls.h +++ b/libpthread/nptl/sysdeps/xtensa/dl-tls.h @@ -28,6 +28,29 @@ typedef struct extern void *__tls_get_addr (tls_index *ti); +/* Type used as the argument in a TLS descriptor for a symbol that + needs dynamic TLS offsets. */ +struct tlsdesc_dynamic_arg +{ + tls_index tlsinfo; + size_t gen_count; +}; + +#ifdef __FDPIC__ +/* Type used to represent a TLS descriptor. */ +struct tlsdesc +{ + ptrdiff_t (*entry)(struct tlsdesc *); + void *argument; +}; + +extern ptrdiff_t attribute_hidden + _dl_tlsdesc_return(struct tlsdesc *); + +extern void *_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset); +extern ptrdiff_t attribute_hidden + _dl_tlsdesc_dynamic(struct tlsdesc *); +#else /* Type used to represent a TLS descriptor. */ struct tlsdesc { @@ -39,19 +62,14 @@ struct tlsdesc ptrdiff_t (*entry)(struct tlsdesc *); }; -/* Type used as the argument in a TLS descriptor for a symbol that - needs dynamic TLS offsets. */ -struct tlsdesc_dynamic_arg -{ - tls_index tlsinfo; - size_t gen_count; -}; - extern ptrdiff_t attribute_hidden _dl_tlsdesc_return(struct tlsdesc_dynamic_arg *); extern void *_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset); extern ptrdiff_t attribute_hidden _dl_tlsdesc_dynamic(struct tlsdesc_dynamic_arg *); - #endif +#endif + +/* Value used for dtv entries for which the allocation is delayed. */ +#define TLS_DTV_UNALLOCATED ((void *) -1l) diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index eab9a3343..dd1f0c514 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -22,6 +22,10 @@ #include <sys/time.h> #include "kernel-posix-cpu-timers.h" +#ifdef __VDSO_SUPPORT__ +#include "ldso.h" +#endif + #if defined(__UCLIBC_USE_TIME64__) #include "internal/time64_helpers.h" #endif @@ -68,9 +72,8 @@ realtime_gettime (struct timespec *tp) return retval; } -/* Get current value of CLOCK and store it in TP. */ int -clock_gettime (clockid_t clock_id, struct timespec *tp) +__libc_clock_gettime (clockid_t clock_id, struct timespec *tp) { int retval = -1; #ifndef HANDLED_REALTIME @@ -101,3 +104,14 @@ clock_gettime (clockid_t clock_id, struct timespec *tp) return retval; } + +/* Get current value of CLOCK and store it in TP. */ +int +clock_gettime (clockid_t clock_id, struct timespec *tp) +{ +#if defined(__VDSO_SUPPORT__) && defined(ARCH_VDSO_CLOCK_GETTIME) + return ARCH_VDSO_CLOCK_GETTIME(clock_id, tp); +#else + return __libc_clock_gettime(clock_id, tp); +#endif +} diff --git a/librt/mq_receive.c b/librt/mq_receive.c index e6fd62b87..217848cca 100644 --- a/librt/mq_receive.c +++ b/librt/mq_receive.c @@ -8,7 +8,7 @@ #include <mqueue.h> -#ifdef __NR_mq_timedreceive +#if defined(__NR_mq_timedreceive) || defined(__NR_mq_timedreceive_time64) ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio) { return mq_timedreceive(mqdes, msg_ptr, msg_len, msg_prio, NULL); diff --git a/librt/mq_send.c b/librt/mq_send.c index fb4fa6555..079e804f7 100644 --- a/librt/mq_send.c +++ b/librt/mq_send.c @@ -8,7 +8,7 @@ #include <mqueue.h> -#ifdef __NR_mq_timedsend +#if defined(__NR_mq_timedsend) || defined(__NR_mq_timedsend_time64) int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio) { return mq_timedsend(mqdes, msg_ptr, msg_len, msg_prio, NULL); diff --git a/libutil/forkpty.c b/libutil/forkpty.c index 24643330c..7e42d1a33 100644 --- a/libutil/forkpty.c +++ b/libutil/forkpty.c @@ -23,7 +23,8 @@ #include <pty.h> int -forkpty (int *amaster, char *name, struct termios *termp, struct winsize *winp) +forkpty (int *amaster, char *name, const struct termios *termp, + const struct winsize *winp) { int master, slave, pid; diff --git a/libutil/openpty.c b/libutil/openpty.c index 848dc8d38..74d86506b 100644 --- a/libutil/openpty.c +++ b/libutil/openpty.c @@ -26,82 +26,18 @@ #include <unistd.h> #include <sys/types.h> -/* BCS: the following function is, IMO, overkill */ -#if 0 -/* Return the result of ptsname_r in the buffer pointed to by PTS, - which should be of length BUF_LEN. If it is too long to fit in - this buffer, a sufficiently long buffer is allocated using malloc, - and returned in PTS. 0 is returned upon success, -1 otherwise. */ -static int -pts_name (int fd, char **pts, size_t buf_len) -{ - int rv; - char *buf = *pts; - - for (;;) - { - char *new_buf; - - if (buf_len) - { - rv = ptsname_r (fd, buf, buf_len); - - if (rv != 0 || memchr (buf, '\0', buf_len)) - /* We either got an error, or we succeeded and the - returned name fit in the buffer. */ - break; - - /* Try again with a longer buffer. */ - buf_len += buf_len; /* Double it */ - } - else - /* No initial buffer; start out by mallocing one. */ - buf_len = 128; /* First time guess. */ - - if (buf != *pts) - /* We've already malloced another buffer at least once. */ - new_buf = realloc (buf, buf_len); - else - new_buf = malloc (buf_len); - if (! new_buf) - { - rv = -1; - __set_errno (ENOMEM); - break; - } - buf = new_buf; - } - - if (rv == 0) - *pts = buf; /* Return buffer to the user. */ - else if (buf != *pts) - free (buf); /* Free what we malloced when returning an error. */ - - return rv; -} -#endif - /* Create pseudo tty master slave pair and set terminal attributes according to TERMP and WINP. Return handles for both ends in AMASTER and ASLAVE, and return the name of the slave end in NAME. */ int -openpty (int *amaster, int *aslave, char *name, struct termios *termp, - struct winsize *winp) +openpty (int *amaster, int *aslave, char *name, const struct termios *termp, + const struct winsize *winp) { -#if 0 -#ifdef PATH_MAX - char _buf[PATH_MAX]; -#else - char _buf[512]; -#endif - char *buf = _buf; -#else #ifdef PATH_MAX char buf[PATH_MAX]; #else char buf[512]; #endif -#endif int master, slave; master = posix_openpt (O_RDWR); @@ -114,20 +50,12 @@ openpty (int *amaster, int *aslave, char *name, struct termios *termp, if (unlockpt (master)) goto fail; -#if 0 - if (pts_name (master, &buf, sizeof (_buf))) -#else if (ptsname_r (master, buf, sizeof buf)) -#endif goto fail; slave = open (buf, O_RDWR | O_NOCTTY); if (slave == -1) { -#if 0 - if (buf != _buf) - free (buf); -#endif goto fail; } @@ -142,10 +70,6 @@ openpty (int *amaster, int *aslave, char *name, struct termios *termp, if (name != NULL) strcpy (name, buf); -#if 0 - if (buf != _buf) - free (buf); -#endif return 0; fail: |