diff options
Diffstat (limited to 'REORG.TODO/sysdeps/mips')
160 files changed, 17202 insertions, 0 deletions
diff --git a/REORG.TODO/sysdeps/mips/Implies b/REORG.TODO/sysdeps/mips/Implies new file mode 100644 index 0000000000..8c18cb3034 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/Implies @@ -0,0 +1,3 @@ +# MIPS uses IEEE 754 floating point. +ieee754/flt-32 +ieee754/dbl-64 diff --git a/REORG.TODO/sysdeps/mips/Makefile b/REORG.TODO/sysdeps/mips/Makefile new file mode 100644 index 0000000000..7c1d77941e --- /dev/null +++ b/REORG.TODO/sysdeps/mips/Makefile @@ -0,0 +1,85 @@ +ifeq ($(subdir),misc) +sysdep_headers += regdef.h fpregdef.h sys/regdef.h sys/fpregdef.h \ + sys/asm.h sgidefs.h +endif + +ifeq ($(subdir),setjmp) +sysdep_routines += setjmp_aux +endif + +ifeq ($(subdir),rt) +librt-sysdep_routines += rt-sysdep +librt-shared-only-routines += rt-sysdep +endif + +ifeq ($(subdir),debug) +CFLAGS-backtrace.c += -funwind-tables +endif + +ifeq ($(subdir),csu) +CPPFLAGS-crti.S += $(pic-ccflag) +CPPFLAGS-crtn.S += $(pic-ccflag) +endif + +ifeq ($(subdir),nptl) +CPPFLAGS-pt-crti.S += $(pic-ccflag) +CPPFLAGS-crtn.S += $(pic-ccflag) +endif + +ASFLAGS-.os += $(pic-ccflag) + +ifeq ($(subdir),elf) +ifneq ($(o32-fpabi),) +tests += tst-abi-interlink + +fpabi-modules-names = +fpabi_list = +ifneq (,$(filter $(o32-fpabi),32 xx xxo)) +fpabi-modules-names += tst-abi-fp32mod +CFLAGS-tst-abi-fp32mod.c += -mfp32 +endif +ifneq (,$(filter $(o32-fpabi),xx)) +fpabi-modules-names += tst-abi-fpxxmod +CFLAGS-tst-abi-fpxxmod.c += -mfpxx -mno-odd-spreg +endif +ifneq (,$(filter $(o32-fpabi),xx xxo)) +ifeq ($(has-modd-spreg),yes) +fpabi-modules-names += tst-abi-fpxxomod +CFLAGS-tst-abi-fpxxomod.c += -mfpxx -modd-spreg +endif +endif +ifneq (,$(filter $(o32-fpabi),xx 64a)) +ifeq ($(has-mpf64),yes) +fpabi-modules-names += tst-abi-fp64amod +CFLAGS-tst-abi-fp64amod.c += -mfp64 -mno-odd-spreg +endif +endif +ifneq (,$(filter $(o32-fpabi),xx xxo 64a 64)) +ifeq ($(has-mpf64)-$(has-modd-spreg),yes-yes) +fpabi-modules-names += tst-abi-fp64mod +CFLAGS-tst-abi-fp64mod.c += -mfp64 -modd-spreg +endif +endif +modules-names += $(fpabi-modules-names) + +comma:=, +empty:= +space:=$(empty) $(empty) +fpabi_list=$(subst $(space),$(comma),$(patsubst tst-abi-%mod,o_%,\ + $(fpabi-modules-names))) +CPPFLAGS-tst-abi-interlink.c += -DFPABI_LIST=$(fpabi_list) +CPPFLAGS-tst-abi-interlink.c += -DFPABI_COUNT=$(words $(fpabi-modules-names)) +CPPFLAGS-tst-abi-interlink.c += -DFPABI_NATIVE=o_fp$(o32-fpabi) +$(objpfx)tst-abi-interlink: $(libdl) +$(objpfx)tst-abi-interlink.out: $(patsubst %,$(objpfx)%.so,\ + $(fpabi-modules-names)) +endif + +ifeq ($(mips-mode-switch),yes) +ifeq ($(o32-fpabi),xx) +tests += tst-mode-switch-1 tst-mode-switch-2 tst-mode-switch-3 +$(objpfx)tst-mode-switch-1: $(shared-thread-library) +$(objpfx)tst-mode-switch-2: $(shared-thread-library) +endif +endif +endif diff --git a/REORG.TODO/sysdeps/mips/__longjmp.c b/REORG.TODO/sysdeps/mips/__longjmp.c new file mode 100644 index 0000000000..03bc1ccf23 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/__longjmp.c @@ -0,0 +1,84 @@ +/* Copyright (C) 1992-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Brendan Kehoe (brendan@zen.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, see + <http://www.gnu.org/licenses/>. */ + +#include <setjmp.h> +#include <stdlib.h> + +#ifndef __GNUC__ + #error This file uses GNU C extensions; you must compile with GCC. +#endif + +static void __attribute__ ((nomips16)) +____longjmp (__jmp_buf env_arg, int val_arg) +{ + /* gcc 1.39.19 miscompiled the longjmp routine (as it did setjmp before + the hack around it); force it to use $a1 for the longjmp value. + Without this it saves $a1 in a register which gets clobbered + along the way. */ + register struct __jmp_buf_internal_tag *env asm ("a0"); + register int val asm ("a1"); +#ifdef CHECK_SP + register long sp asm ("$29"); + CHECK_SP (env[0].__sp, sp, long); +#endif + +#ifdef __mips_hard_float + /* Pull back the floating point callee-saved registers. */ + asm volatile ("l.d $f20, %0" : : "m" (env[0].__fpregs[0])); + asm volatile ("l.d $f22, %0" : : "m" (env[0].__fpregs[1])); + asm volatile ("l.d $f24, %0" : : "m" (env[0].__fpregs[2])); + asm volatile ("l.d $f26, %0" : : "m" (env[0].__fpregs[3])); + asm volatile ("l.d $f28, %0" : : "m" (env[0].__fpregs[4])); + asm volatile ("l.d $f30, %0" : : "m" (env[0].__fpregs[5])); +#endif + + /* Get the GP. */ + asm volatile ("lw $gp, %0" : : "m" (env[0].__gp)); + + /* Get the callee-saved registers. */ + asm volatile ("lw $16, %0" : : "m" (env[0].__regs[0])); + asm volatile ("lw $17, %0" : : "m" (env[0].__regs[1])); + asm volatile ("lw $18, %0" : : "m" (env[0].__regs[2])); + asm volatile ("lw $19, %0" : : "m" (env[0].__regs[3])); + asm volatile ("lw $20, %0" : : "m" (env[0].__regs[4])); + asm volatile ("lw $21, %0" : : "m" (env[0].__regs[5])); + asm volatile ("lw $22, %0" : : "m" (env[0].__regs[6])); + asm volatile ("lw $23, %0" : : "m" (env[0].__regs[7])); + + /* Get the PC. */ + asm volatile ("lw $25, %0" : : "m" (env[0].__pc)); + + /* Restore the stack pointer and the FP. They have to be restored + last and in a single asm as gcc, depending on options used, may + use either of them to access env. */ + asm volatile ("lw $29, %0\n\t" + "lw $30, %1\n\t" : : "m" (env[0].__sp), "m" (env[0].__fp)); + +/* Give setjmp 1 if given a 0, or what they gave us if non-zero. */ + if (val == 0) + asm volatile ("li $2, 1"); + else + asm volatile ("move $2, %0" : : "r" (val)); + + asm volatile ("jr $25"); + + /* Avoid `volatile function does return' warnings. */ + for (;;); +} + +strong_alias (____longjmp, __longjmp); diff --git a/REORG.TODO/sysdeps/mips/abort-instr.h b/REORG.TODO/sysdeps/mips/abort-instr.h new file mode 100644 index 0000000000..7ccae5736b --- /dev/null +++ b/REORG.TODO/sysdeps/mips/abort-instr.h @@ -0,0 +1,6 @@ +/* An instruction which should crash any program is a breakpoint. */ +#ifdef __mips16 +# define ABORT_INSTRUCTION asm ("break 63") +#else +# define ABORT_INSTRUCTION asm ("break 255") +#endif diff --git a/REORG.TODO/sysdeps/mips/add_n.S b/REORG.TODO/sysdeps/mips/add_n.S new file mode 100644 index 0000000000..823778feb7 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/add_n.S @@ -0,0 +1,121 @@ +/* MIPS2 __mpn_add_n -- Add two limb vectors of the same length > 0 and +store sum in a third limb vector. + +Copyright (C) 1995-2017 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library. If not, see +<http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +/* INPUT PARAMETERS + res_ptr $4 + s1_ptr $5 + s2_ptr $6 + size $7 +*/ +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__mpn_add_n) + .set noreorder +#ifdef __PIC__ + .cpload t9 +#endif + .set nomacro + + lw $10,0($5) + lw $11,0($6) + + addiu $7,$7,-1 + and $9,$7,4-1 /* number of limbs in first loop */ + beq $9,$0,L(L0) /* if multiple of 4 limbs, skip first loop */ + move $2,$0 + + subu $7,$7,$9 + +L(Loop0): addiu $9,$9,-1 + lw $12,4($5) + addu $11,$11,$2 + lw $13,4($6) + sltu $8,$11,$2 + addu $11,$10,$11 + sltu $2,$11,$10 + sw $11,0($4) + or $2,$2,$8 + + addiu $5,$5,4 + addiu $6,$6,4 + move $10,$12 + move $11,$13 + bne $9,$0,L(Loop0) + addiu $4,$4,4 + +L(L0): beq $7,$0,L(end) + nop + +L(Loop): addiu $7,$7,-4 + + lw $12,4($5) + addu $11,$11,$2 + lw $13,4($6) + sltu $8,$11,$2 + addu $11,$10,$11 + sltu $2,$11,$10 + sw $11,0($4) + or $2,$2,$8 + + lw $10,8($5) + addu $13,$13,$2 + lw $11,8($6) + sltu $8,$13,$2 + addu $13,$12,$13 + sltu $2,$13,$12 + sw $13,4($4) + or $2,$2,$8 + + lw $12,12($5) + addu $11,$11,$2 + lw $13,12($6) + sltu $8,$11,$2 + addu $11,$10,$11 + sltu $2,$11,$10 + sw $11,8($4) + or $2,$2,$8 + + lw $10,16($5) + addu $13,$13,$2 + lw $11,16($6) + sltu $8,$13,$2 + addu $13,$12,$13 + sltu $2,$13,$12 + sw $13,12($4) + or $2,$2,$8 + + addiu $5,$5,16 + addiu $6,$6,16 + + bne $7,$0,L(Loop) + addiu $4,$4,16 + +L(end): addu $11,$11,$2 + sltu $8,$11,$2 + addu $11,$10,$11 + sltu $2,$11,$10 + sw $11,0($4) + j $31 + or $2,$2,$8 +END (__mpn_add_n) diff --git a/REORG.TODO/sysdeps/mips/addmul_1.S b/REORG.TODO/sysdeps/mips/addmul_1.S new file mode 100644 index 0000000000..7a664934b2 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/addmul_1.S @@ -0,0 +1,128 @@ +/* MIPS __mpn_addmul_1 -- Multiply a limb vector with a single limb and +add the product to a second limb vector. + +Copyright (C) 1995-2017 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library. If not, see +<http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +/* INPUT PARAMETERS + res_ptr $4 + s1_ptr $5 + size $6 + s2_limb $7 +*/ +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__mpn_addmul_1) + .set noreorder +#ifdef __PIC__ + .cpload t9 +#endif + .set nomacro + + /* warm up phase 0 */ + lw $8,0($5) + + /* warm up phase 1 */ + addiu $5,$5,4 +#if __mips_isa_rev < 6 + multu $8,$7 +#else + mulu $11,$8,$7 + muhu $12,$8,$7 +#endif + + addiu $6,$6,-1 + beq $6,$0,L(LC0) + move $2,$0 /* zero cy2 */ + + addiu $6,$6,-1 + beq $6,$0,L(LC1) + lw $8,0($5) /* load new s1 limb as early as possible */ + +L(Loop): lw $10,0($4) +#if __mips_isa_rev < 6 + mflo $3 + mfhi $9 +#else + move $3,$11 + move $9,$12 +#endif + addiu $5,$5,4 + addu $3,$3,$2 /* add old carry limb to low product limb */ +#if __mips_isa_rev < 6 + multu $8,$7 +#else + mulu $11,$8,$7 + muhu $12,$8,$7 +#endif + lw $8,0($5) /* load new s1 limb as early as possible */ + addiu $6,$6,-1 /* decrement loop counter */ + sltu $2,$3,$2 /* carry from previous addition -> $2 */ + addu $3,$10,$3 + sltu $10,$3,$10 + addu $2,$2,$10 + sw $3,0($4) + addiu $4,$4,4 + bne $6,$0,L(Loop) /* should be "bnel" */ + addu $2,$9,$2 /* add high product limb and carry from addition */ + + /* cool down phase 1 */ +L(LC1): lw $10,0($4) +#if __mips_isa_rev < 6 + mflo $3 + mfhi $9 +#else + move $3,$11 + move $9,$12 +#endif + addu $3,$3,$2 + sltu $2,$3,$2 +#if __mips_isa_rev < 6 + multu $8,$7 +#else + mulu $11,$8,$7 + muhu $12,$8,$7 +#endif + addu $3,$10,$3 + sltu $10,$3,$10 + addu $2,$2,$10 + sw $3,0($4) + addiu $4,$4,4 + addu $2,$9,$2 /* add high product limb and carry from addition */ + + /* cool down phase 0 */ +L(LC0): lw $10,0($4) +#if __mips_isa_rev < 6 + mflo $3 + mfhi $9 +#else + move $3,$11 + move $9,$12 +#endif + addu $3,$3,$2 + sltu $2,$3,$2 + addu $3,$10,$3 + sltu $10,$3,$10 + addu $2,$2,$10 + sw $3,0($4) + j $31 + addu $2,$9,$2 /* add high product limb and carry from addition */ + END (__mpn_addmul_1) diff --git a/REORG.TODO/sysdeps/mips/atomic-machine.h b/REORG.TODO/sysdeps/mips/atomic-machine.h new file mode 100644 index 0000000000..16fef6b797 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/atomic-machine.h @@ -0,0 +1,479 @@ +/* Low-level functions for atomic operations. Mips version. + Copyright (C) 2005-2017 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 _MIPS_ATOMIC_MACHINE_H +#define _MIPS_ATOMIC_MACHINE_H 1 + +#include <stdint.h> +#include <inttypes.h> +#include <sgidefs.h> + +typedef int32_t atomic32_t; +typedef uint32_t uatomic32_t; +typedef int_fast32_t atomic_fast32_t; +typedef uint_fast32_t uatomic_fast32_t; + +typedef int64_t atomic64_t; +typedef uint64_t uatomic64_t; +typedef int_fast64_t atomic_fast64_t; +typedef uint_fast64_t uatomic_fast64_t; + +typedef intptr_t atomicptr_t; +typedef uintptr_t uatomicptr_t; +typedef intmax_t atomic_max_t; +typedef uintmax_t uatomic_max_t; + +#if _MIPS_SIM == _ABIO32 && __mips < 2 +#define MIPS_PUSH_MIPS2 ".set mips2\n\t" +#else +#define MIPS_PUSH_MIPS2 +#endif + +#if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32 +#define __HAVE_64B_ATOMICS 0 +#else +#define __HAVE_64B_ATOMICS 1 +#endif + +/* See the comments in <sys/asm.h> about the use of the sync instruction. */ +#ifndef MIPS_SYNC +# define MIPS_SYNC sync +#endif + +/* Certain revisions of the R10000 Processor need an LL/SC Workaround + enabled. Revisions before 3.0 misbehave on atomic operations, and + Revs 2.6 and lower deadlock after several seconds due to other errata. + + To quote the R10K Errata: + Workaround: The basic idea is to inhibit the four instructions + from simultaneously becoming active in R10000. Padding all + ll/sc sequences with nops or changing the looping branch in the + routines to a branch likely (which is always predicted taken + by R10000) will work. The nops should go after the loop, and the + number of them should be 28. This number could be decremented for + each additional instruction in the ll/sc loop such as the lock + modifier(s) between the ll and sc, the looping branch and its + delay slot. For typical short routines with one ll/sc loop, any + instructions after the loop could also count as a decrement. The + nop workaround pollutes the cache more but would be a few cycles + faster if all the code is in the cache and the looping branch + is predicted not taken. */ + + +#ifdef _MIPS_ARCH_R10000 +#define R10K_BEQZ_INSN "beqzl" +#else +#define R10K_BEQZ_INSN "beqz" +#endif + +#define MIPS_SYNC_STR_2(X) #X +#define MIPS_SYNC_STR_1(X) MIPS_SYNC_STR_2(X) +#define MIPS_SYNC_STR MIPS_SYNC_STR_1(MIPS_SYNC) + +#if __GNUC_PREREQ (4, 8) || defined __mips16 +/* The __atomic_* builtins are available in GCC 4.7 and later, but MIPS + support for their efficient implementation was added only in GCC 4.8. + We still want to use them even with GCC 4.7 for MIPS16 code where we + have no assembly alternative available and want to avoid the __sync_* + builtins if at all possible. */ + +# define USE_ATOMIC_COMPILER_BUILTINS 1 + +/* MIPS is an LL/SC machine. However, XLP has a direct atomic exchange + instruction which will be used by __atomic_exchange_n. */ +# ifdef _MIPS_ARCH_XLP +# define ATOMIC_EXCHANGE_USES_CAS 0 +# else +# define ATOMIC_EXCHANGE_USES_CAS 1 +# endif + +/* Compare and exchange. + For all "bool" routines, we return FALSE if exchange succesful. */ + +# define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \ + (abort (), 0) + +# define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \ + (abort (), 0) + +# define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + }) + +# define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \ + (abort (), (typeof(*mem)) 0) + +# define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \ + (abort (), (typeof(*mem)) 0) + +# define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + +# if _MIPS_SIM == _ABIO32 + /* We can't do an atomic 64-bit operation in O32. */ +# define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \ + (abort (), 0) +# define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \ + (abort (), (typeof(*mem)) 0) +# else +# define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \ + __arch_compare_and_exchange_bool_32_int (mem, newval, oldval, model) +# define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \ + __arch_compare_and_exchange_val_32_int (mem, newval, oldval, model) +# endif + +/* Compare and exchange with "acquire" semantics, ie barrier after. */ + +# define atomic_compare_and_exchange_bool_acq(mem, new, old) \ + __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \ + mem, new, old, __ATOMIC_ACQUIRE) + +# define atomic_compare_and_exchange_val_acq(mem, new, old) \ + __atomic_val_bysize (__arch_compare_and_exchange_val, int, \ + mem, new, old, __ATOMIC_ACQUIRE) + +/* Compare and exchange with "release" semantics, ie barrier before. */ + +# define atomic_compare_and_exchange_val_rel(mem, new, old) \ + __atomic_val_bysize (__arch_compare_and_exchange_val, int, \ + mem, new, old, __ATOMIC_RELEASE) + + +/* Atomic exchange (without compare). */ + +# define __arch_exchange_8_int(mem, newval, model) \ + (abort (), (typeof(*mem)) 0) + +# define __arch_exchange_16_int(mem, newval, model) \ + (abort (), (typeof(*mem)) 0) + +# define __arch_exchange_32_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +# if _MIPS_SIM == _ABIO32 +/* We can't do an atomic 64-bit operation in O32. */ +# define __arch_exchange_64_int(mem, newval, model) \ + (abort (), (typeof(*mem)) 0) +# else +# define __arch_exchange_64_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) +# endif + +# define atomic_exchange_acq(mem, value) \ + __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE) + +# define atomic_exchange_rel(mem, value) \ + __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE) + + +/* Atomically add value and return the previous (unincremented) value. */ + +# define __arch_exchange_and_add_8_int(mem, value, model) \ + (abort (), (typeof(*mem)) 0) + +# define __arch_exchange_and_add_16_int(mem, value, model) \ + (abort (), (typeof(*mem)) 0) + +# define __arch_exchange_and_add_32_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +# if _MIPS_SIM == _ABIO32 +/* We can't do an atomic 64-bit operation in O32. */ +# define __arch_exchange_and_add_64_int(mem, value, model) \ + (abort (), (typeof(*mem)) 0) +# else +# define __arch_exchange_and_add_64_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) +# endif + +# define atomic_exchange_and_add_acq(mem, value) \ + __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ + __ATOMIC_ACQUIRE) + +# define atomic_exchange_and_add_rel(mem, value) \ + __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ + __ATOMIC_RELEASE) + +#else /* !__mips16 && !__GNUC_PREREQ (4, 8) */ +/* This implementation using inline assembly will be removed once glibc + requires GCC 4.8 or later to build. */ + +# define USE_ATOMIC_COMPILER_BUILTINS 0 +# define ATOMIC_EXCHANGE_USES_CAS 1 + +/* Compare and exchange. For all of the "xxx" routines, we expect a + "__prev" and a "__cmp" variable to be provided by the enclosing scope, + in which values are returned. */ + +# define __arch_compare_and_exchange_xxx_8_int(mem, newval, oldval, rel, acq) \ + (abort (), __prev = 0, __cmp = 0, (void) __cmp) + +# define __arch_compare_and_exchange_xxx_16_int(mem, newval, oldval, rel, acq) \ + (abort (), __prev = 0, __cmp = 0, (void) __cmp) + +# define __arch_compare_and_exchange_xxx_32_int(mem, newval, oldval, rel, acq) \ + __asm__ __volatile__ ( \ + ".set push\n\t" \ + MIPS_PUSH_MIPS2 \ + rel "\n" \ + "1:\t" \ + "ll %0,%5\n\t" \ + "move %1,$0\n\t" \ + "bne %0,%3,2f\n\t" \ + "move %1,%4\n\t" \ + "sc %1,%2\n\t" \ + R10K_BEQZ_INSN" %1,1b\n" \ + acq "\n\t" \ + ".set pop\n" \ + "2:\n\t" \ + : "=&r" (__prev), "=&r" (__cmp), "=m" (*mem) \ + : "r" (oldval), "r" (newval), "m" (*mem) \ + : "memory") + +# if _MIPS_SIM == _ABIO32 +/* We can't do an atomic 64-bit operation in O32. */ +# define __arch_compare_and_exchange_xxx_64_int(mem, newval, oldval, rel, acq) \ + (abort (), __prev = 0, __cmp = 0, (void) __cmp) +# else +# define __arch_compare_and_exchange_xxx_64_int(mem, newval, oldval, rel, acq) \ + __asm__ __volatile__ ("\n" \ + ".set push\n\t" \ + MIPS_PUSH_MIPS2 \ + rel "\n" \ + "1:\t" \ + "lld %0,%5\n\t" \ + "move %1,$0\n\t" \ + "bne %0,%3,2f\n\t" \ + "move %1,%4\n\t" \ + "scd %1,%2\n\t" \ + R10K_BEQZ_INSN" %1,1b\n" \ + acq "\n\t" \ + ".set pop\n" \ + "2:\n\t" \ + : "=&r" (__prev), "=&r" (__cmp), "=m" (*mem) \ + : "r" (oldval), "r" (newval), "m" (*mem) \ + : "memory") +# endif + +/* For all "bool" routines, we return FALSE if exchange succesful. */ + +# define __arch_compare_and_exchange_bool_8_int(mem, new, old, rel, acq) \ +({ typeof (*mem) __prev __attribute__ ((unused)); int __cmp; \ + __arch_compare_and_exchange_xxx_8_int(mem, new, old, rel, acq); \ + !__cmp; }) + +# define __arch_compare_and_exchange_bool_16_int(mem, new, old, rel, acq) \ +({ typeof (*mem) __prev __attribute__ ((unused)); int __cmp; \ + __arch_compare_and_exchange_xxx_16_int(mem, new, old, rel, acq); \ + !__cmp; }) + +# define __arch_compare_and_exchange_bool_32_int(mem, new, old, rel, acq) \ +({ typeof (*mem) __prev __attribute__ ((unused)); int __cmp; \ + __arch_compare_and_exchange_xxx_32_int(mem, new, old, rel, acq); \ + !__cmp; }) + +# define __arch_compare_and_exchange_bool_64_int(mem, new, old, rel, acq) \ +({ typeof (*mem) __prev __attribute__ ((unused)); int __cmp; \ + __arch_compare_and_exchange_xxx_64_int(mem, new, old, rel, acq); \ + !__cmp; }) + +/* For all "val" routines, return the old value whether exchange + successful or not. */ + +# define __arch_compare_and_exchange_val_8_int(mem, new, old, rel, acq) \ +({ typeof (*mem) __prev; int __cmp; \ + __arch_compare_and_exchange_xxx_8_int(mem, new, old, rel, acq); \ + (typeof (*mem))__prev; }) + +# define __arch_compare_and_exchange_val_16_int(mem, new, old, rel, acq) \ +({ typeof (*mem) __prev; int __cmp; \ + __arch_compare_and_exchange_xxx_16_int(mem, new, old, rel, acq); \ + (typeof (*mem))__prev; }) + +# define __arch_compare_and_exchange_val_32_int(mem, new, old, rel, acq) \ +({ typeof (*mem) __prev; int __cmp; \ + __arch_compare_and_exchange_xxx_32_int(mem, new, old, rel, acq); \ + (typeof (*mem))__prev; }) + +# define __arch_compare_and_exchange_val_64_int(mem, new, old, rel, acq) \ +({ typeof (*mem) __prev; int __cmp; \ + __arch_compare_and_exchange_xxx_64_int(mem, new, old, rel, acq); \ + (typeof (*mem))__prev; }) + +/* Compare and exchange with "acquire" semantics, ie barrier after. */ + +# define atomic_compare_and_exchange_bool_acq(mem, new, old) \ + __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \ + mem, new, old, "", MIPS_SYNC_STR) + +# define atomic_compare_and_exchange_val_acq(mem, new, old) \ + __atomic_val_bysize (__arch_compare_and_exchange_val, int, \ + mem, new, old, "", MIPS_SYNC_STR) + +/* Compare and exchange with "release" semantics, ie barrier before. */ + +# define atomic_compare_and_exchange_val_rel(mem, new, old) \ + __atomic_val_bysize (__arch_compare_and_exchange_val, int, \ + mem, new, old, MIPS_SYNC_STR, "") + + + +/* Atomic exchange (without compare). */ + +# define __arch_exchange_xxx_8_int(mem, newval, rel, acq) \ + (abort (), (typeof(*mem)) 0) + +# define __arch_exchange_xxx_16_int(mem, newval, rel, acq) \ + (abort (), (typeof(*mem)) 0) + +# define __arch_exchange_xxx_32_int(mem, newval, rel, acq) \ +({ typeof (*mem) __prev; int __cmp; \ + __asm__ __volatile__ ("\n" \ + ".set push\n\t" \ + MIPS_PUSH_MIPS2 \ + rel "\n" \ + "1:\t" \ + "ll %0,%4\n\t" \ + "move %1,%3\n\t" \ + "sc %1,%2\n\t" \ + R10K_BEQZ_INSN" %1,1b\n" \ + acq "\n\t" \ + ".set pop\n" \ + "2:\n\t" \ + : "=&r" (__prev), "=&r" (__cmp), "=m" (*mem) \ + : "r" (newval), "m" (*mem) \ + : "memory"); \ + __prev; }) + +# if _MIPS_SIM == _ABIO32 +/* We can't do an atomic 64-bit operation in O32. */ +# define __arch_exchange_xxx_64_int(mem, newval, rel, acq) \ + (abort (), (typeof(*mem)) 0) +# else +# define __arch_exchange_xxx_64_int(mem, newval, rel, acq) \ +({ typeof (*mem) __prev; int __cmp; \ + __asm__ __volatile__ ("\n" \ + ".set push\n\t" \ + MIPS_PUSH_MIPS2 \ + rel "\n" \ + "1:\n" \ + "lld %0,%4\n\t" \ + "move %1,%3\n\t" \ + "scd %1,%2\n\t" \ + R10K_BEQZ_INSN" %1,1b\n" \ + acq "\n\t" \ + ".set pop\n" \ + "2:\n\t" \ + : "=&r" (__prev), "=&r" (__cmp), "=m" (*mem) \ + : "r" (newval), "m" (*mem) \ + : "memory"); \ + __prev; }) +# endif + +# define atomic_exchange_acq(mem, value) \ + __atomic_val_bysize (__arch_exchange_xxx, int, mem, value, "", MIPS_SYNC_STR) + +# define atomic_exchange_rel(mem, value) \ + __atomic_val_bysize (__arch_exchange_xxx, int, mem, value, MIPS_SYNC_STR, "") + + +/* Atomically add value and return the previous (unincremented) value. */ + +# define __arch_exchange_and_add_8_int(mem, newval, rel, acq) \ + (abort (), (typeof(*mem)) 0) + +# define __arch_exchange_and_add_16_int(mem, newval, rel, acq) \ + (abort (), (typeof(*mem)) 0) + +# define __arch_exchange_and_add_32_int(mem, value, rel, acq) \ +({ typeof (*mem) __prev; int __cmp; \ + __asm__ __volatile__ ("\n" \ + ".set push\n\t" \ + MIPS_PUSH_MIPS2 \ + rel "\n" \ + "1:\t" \ + "ll %0,%4\n\t" \ + "addu %1,%0,%3\n\t" \ + "sc %1,%2\n\t" \ + R10K_BEQZ_INSN" %1,1b\n" \ + acq "\n\t" \ + ".set pop\n" \ + "2:\n\t" \ + : "=&r" (__prev), "=&r" (__cmp), "=m" (*mem) \ + : "r" (value), "m" (*mem) \ + : "memory"); \ + __prev; }) + +# if _MIPS_SIM == _ABIO32 +/* We can't do an atomic 64-bit operation in O32. */ +# define __arch_exchange_and_add_64_int(mem, value, rel, acq) \ + (abort (), (typeof(*mem)) 0) +# else +# define __arch_exchange_and_add_64_int(mem, value, rel, acq) \ +({ typeof (*mem) __prev; int __cmp; \ + __asm__ __volatile__ ( \ + ".set push\n\t" \ + MIPS_PUSH_MIPS2 \ + rel "\n" \ + "1:\t" \ + "lld %0,%4\n\t" \ + "daddu %1,%0,%3\n\t" \ + "scd %1,%2\n\t" \ + R10K_BEQZ_INSN" %1,1b\n" \ + acq "\n\t" \ + ".set pop\n" \ + "2:\n\t" \ + : "=&r" (__prev), "=&r" (__cmp), "=m" (*mem) \ + : "r" (value), "m" (*mem) \ + : "memory"); \ + __prev; }) +# endif + +# define atomic_exchange_and_add_acq(mem, value) \ + __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ + "", MIPS_SYNC_STR) + +# define atomic_exchange_and_add_rel(mem, value) \ + __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ + MIPS_SYNC_STR, "") + +#endif /* !__mips16 && !__GNUC_PREREQ (4, 8) */ + +/* TODO: More atomic operations could be implemented efficiently; only the + basic requirements are done. */ + +#ifdef __mips16 +# define atomic_full_barrier() __sync_synchronize () + +#else /* !__mips16 */ +# define atomic_full_barrier() \ + __asm__ __volatile__ (".set push\n\t" \ + MIPS_PUSH_MIPS2 \ + MIPS_SYNC_STR "\n\t" \ + ".set pop" : : : "memory") +#endif /* !__mips16 */ + +#endif /* atomic-machine.h */ diff --git a/REORG.TODO/sysdeps/mips/backtrace.c b/REORG.TODO/sysdeps/mips/backtrace.c new file mode 100644 index 0000000000..27ce597b39 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/backtrace.c @@ -0,0 +1 @@ +#include <sysdeps/x86_64/backtrace.c> diff --git a/REORG.TODO/sysdeps/mips/bits/dlfcn.h b/REORG.TODO/sysdeps/mips/bits/dlfcn.h new file mode 100644 index 0000000000..95b2fa0973 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/bits/dlfcn.h @@ -0,0 +1,64 @@ +/* System dependent definitions for run-time dynamic loading. + Copyright (C) 1996-2017 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 _DLFCN_H +# error "Never use <bits/dlfcn.h> directly; include <dlfcn.h> instead." +#endif + +/* The MODE argument to `dlopen' contains one of the following: */ +#define RTLD_LAZY 0x0001 /* Lazy function call binding. */ +#define RTLD_NOW 0x0002 /* Immediate function call binding. */ +#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */ +#define RTLD_NOLOAD 0x00008 /* Do not load the object. */ +#define RTLD_DEEPBIND 0x00010 /* Use deep binding. */ + +/* If the following bit is set in the MODE argument to `dlopen', + the symbols of the loaded object and its dependencies are made + visible as if the object were linked directly into the program. */ +#define RTLD_GLOBAL 0x0004 + +/* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL. + The implementation does this by default and so we can define the + value to zero. */ +#define RTLD_LOCAL 0 + +/* Do not delete object when closed. */ +#define RTLD_NODELETE 0x01000 + +#ifdef __USE_GNU +/* To support profiling of shared objects it is a good idea to call + the function found using `dlsym' using the following macro since + these calls do not use the PLT. But this would mean the dynamic + loader has no chance to find out when the function is called. The + macro applies the necessary magic so that profiling is possible. + Rewrite + foo = (*fctp) (arg1, arg2); + into + foo = DL_CALL_FCT (fctp, (arg1, arg2)); +*/ +# define DL_CALL_FCT(fctp, args) \ + (_dl_mcount_wrapper_check ((void *) (fctp)), (*(fctp)) args) + +__BEGIN_DECLS + +/* This function calls the profiling functions. */ +extern void _dl_mcount_wrapper_check (void *__selfpc) __THROW; + +__END_DECLS + +#endif diff --git a/REORG.TODO/sysdeps/mips/bits/endian.h b/REORG.TODO/sysdeps/mips/bits/endian.h new file mode 100644 index 0000000000..126059799d --- /dev/null +++ b/REORG.TODO/sysdeps/mips/bits/endian.h @@ -0,0 +1,15 @@ +/* The MIPS architecture has selectable endianness. + It exists in both little and big endian flavours and we + want to be able to share the installed header files between + both, so we define __BYTE_ORDER based on GCC's predefines. */ + +#ifndef _ENDIAN_H +# error "Never use <bits/endian.h> directly; include <endian.h> instead." +#endif + +#ifdef __MIPSEB +# define __BYTE_ORDER __BIG_ENDIAN +#endif +#ifdef __MIPSEL +# define __BYTE_ORDER __LITTLE_ENDIAN +#endif diff --git a/REORG.TODO/sysdeps/mips/bits/fenv.h b/REORG.TODO/sysdeps/mips/bits/fenv.h new file mode 100644 index 0000000000..a3195ea474 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/bits/fenv.h @@ -0,0 +1,93 @@ +/* Copyright (C) 1998-2017 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 _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 FPU control word. */ +enum + { + 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 MIPS 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 + 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 + }; + + +/* Type representing exception flags. */ +typedef unsigned short int fexcept_t; + + +/* Type representing floating-point environment. This function corresponds + to the layout of the block written by the `fstenv'. */ +typedef struct + { + unsigned int __fp_control_register; + } +fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((const fenv_t *) -1) + +#ifdef __USE_GNU +/* Floating-point environment where none of the exception is masked. */ +# define FE_NOMASK_ENV ((const fenv_t *) -2) +#endif + +#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/REORG.TODO/sysdeps/mips/bits/ipctypes.h b/REORG.TODO/sysdeps/mips/bits/ipctypes.h new file mode 100644 index 0000000000..9596c290dd --- /dev/null +++ b/REORG.TODO/sysdeps/mips/bits/ipctypes.h @@ -0,0 +1,31 @@ +/* bits/ipctypes.h -- Define some types used by SysV IPC/MSG/SHM. MIPS version + Copyright (C) 2002-2017 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/>. */ + +/* + * Never include <bits/ipctypes.h> directly. + */ + +#ifndef _BITS_IPCTYPES_H +#define _BITS_IPCTYPES_H 1 + +#include <bits/types.h> + +typedef __SLONG32_TYPE __ipc_pid_t; + + +#endif /* bits/ipctypes.h */ diff --git a/REORG.TODO/sysdeps/mips/bits/link.h b/REORG.TODO/sysdeps/mips/bits/link.h new file mode 100644 index 0000000000..e32dad5633 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/bits/link.h @@ -0,0 +1,117 @@ +/* Copyright (C) 2005-2017 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 _LINK_H +# error "Never include <bits/link.h> directly; use <link.h> instead." +#endif + +#include <sgidefs.h> + +#if _MIPS_SIM == _ABIO32 + +/* Registers for entry into PLT on MIPS. */ +typedef struct La_mips_32_regs +{ + uint32_t lr_reg[4]; /* $a0 through $a3 */ + double lr_fpreg[2]; /* $f12 and $f14 */ + uint32_t lr_ra; + uint32_t lr_sp; +} La_mips_32_regs; + +/* Return values for calls from PLT on MIPS. */ +typedef struct La_mips_32_retval +{ + uint32_t lrv_v0; + uint32_t lrv_v1; + double lrv_f0; + double lrv_f2; +} La_mips_32_retval; + +#else + +typedef struct La_mips_64_regs +{ + uint64_t lr_reg[8]; /* $a0 through $a7 */ + double lr_fpreg[8]; /* $f12 throgh $f19 */ + uint64_t lr_ra; + uint64_t lr_sp; +} La_mips_64_regs; + +/* Return values for calls from PLT on MIPS. */ +typedef struct La_mips_64_retval +{ + uint64_t lrv_v0; + uint64_t lrv_v1; + double lrv_f0; + double lrv_f2; +} La_mips_64_retval; + +#endif + +__BEGIN_DECLS + +#if _MIPS_SIM == _ABIO32 + +extern Elf32_Addr la_mips_o32_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + La_mips_32_regs *__regs, + unsigned int *__flags, + const char *__symname, + long int *__framesizep); +extern unsigned int la_mips_o32_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + const La_mips_32_regs *__inregs, + La_mips_32_retval *__outregs, + const char *__symname); + +#elif _MIPS_SIM == _ABIN32 + +extern Elf32_Addr la_mips_n32_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + La_mips_64_regs *__regs, + unsigned int *__flags, + const char *__symname, + long int *__framesizep); +extern unsigned int la_mips_n32_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + const La_mips_64_regs *__inregs, + La_mips_64_retval *__outregs, + const char *__symname); + +#else + +extern Elf64_Addr la_mips_n64_gnu_pltenter (Elf64_Sym *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + La_mips_64_regs *__regs, + unsigned int *__flags, + const char *__symname, + long int *__framesizep); +extern unsigned int la_mips_n64_gnu_pltexit (Elf64_Sym *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + const La_mips_64_regs *__inregs, + La_mips_64_retval *__outregs, + const char *__symname); + +#endif + +__END_DECLS diff --git a/REORG.TODO/sysdeps/mips/bits/long-double.h b/REORG.TODO/sysdeps/mips/bits/long-double.h new file mode 100644 index 0000000000..604188e181 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/bits/long-double.h @@ -0,0 +1,23 @@ +/* Properties of long double type. MIPS version. + Copyright (C) 2016-2017 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 published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <sgidefs.h> + +#if !defined __NO_LONG_DOUBLE_MATH && _MIPS_SIM == _ABIO32 +# define __NO_LONG_DOUBLE_MATH 1 +#endif diff --git a/REORG.TODO/sysdeps/mips/bits/nan.h b/REORG.TODO/sysdeps/mips/bits/nan.h new file mode 100644 index 0000000000..a4a1ef9f06 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/bits/nan.h @@ -0,0 +1,67 @@ +/* `NAN' constant for IEEE 754 machines. MIPS version. + Copyright (C) 1992-2017 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 _MATH_H +# error "Never use <bits/nan.h> directly; include <math.h> instead." +#endif + + +/* IEEE Not A Number. */ +/* In legacy-NaN mode MIPS has the qNaN and sNaN patterns reversed + compared to most other architectures. IEEE 754-1985 left the + definition of this open to implementations, and for MIPS the top bit + of the mantissa must be SET to indicate a sNaN. In 2008-NaN mode + MIPS aligned to IEEE 754-2008. */ + +#if __GNUC_PREREQ(3,3) + +# define NAN (__builtin_nanf ("")) + +#elif defined __GNUC__ + +/* No 2008-NaN mode support in any GCC version before 4.9. */ + +# define NAN \ + (__extension__ \ + ((union { unsigned __l __attribute__ ((__mode__ (__SI__))); float __d; }) \ + { __l: 0x7fbfffffUL }).__d) + +#else + +# include <endian.h> + +# if __BYTE_ORDER == __BIG_ENDIAN +# ifdef __mips_nan2008 +# define __qnan_bytes { 0x7f, 0xc0, 0, 0 } +# else +# define __qnan_bytes { 0x7f, 0xbf, 0xff, 0xff } +# endif +# endif +# if __BYTE_ORDER == __LITTLE_ENDIAN +# ifdef __mips_nan2008 +# define __qnan_bytes { 0, 0, 0xc0, 0x7f } +# else +# define __qnan_bytes { 0xff, 0xff, 0xbf, 0x7f } +# endif +# endif + +static union { unsigned char __c[4]; float __d; } __qnan_union + __attribute__ ((__unused__)) = { __qnan_bytes }; +# define NAN (__qnan_union.__d) + +#endif /* GCC. */ diff --git a/REORG.TODO/sysdeps/mips/bits/setjmp.h b/REORG.TODO/sysdeps/mips/bits/setjmp.h new file mode 100644 index 0000000000..91c64505f4 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/bits/setjmp.h @@ -0,0 +1,73 @@ +/* Define the machine-dependent type `jmp_buf'. MIPS version. + Copyright (C) 1992-2017 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 _MIPS_BITS_SETJMP_H +#define _MIPS_BITS_SETJMP_H 1 + +#if !defined(_SETJMP_H) && !defined(_PTHREAD_H) +# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead." +#endif + +#include <sgidefs.h> + +typedef struct __jmp_buf_internal_tag + { +#if _MIPS_SIM == _ABIO32 + /* Program counter. */ + __ptr_t __pc; + + /* Stack pointer. */ + __ptr_t __sp; + + /* Callee-saved registers s0 through s7. */ + int __regs[8]; + + /* The frame pointer. */ + __ptr_t __fp; + + /* The global pointer. */ + __ptr_t __gp; +#else + /* Program counter. */ + __extension__ long long __pc; + + /* Stack pointer. */ + __extension__ long long __sp; + + /* Callee-saved registers s0 through s7. */ + __extension__ long long __regs[8]; + + /* The frame pointer. */ + __extension__ long long __fp; + + /* The global pointer. */ + __extension__ long long __gp; +#endif + + /* Unused (was floating point status register). */ + int __glibc_reserved1; + + /* Callee-saved floating point registers. */ +#if _MIPS_SIM == _ABI64 + double __fpregs[8]; +#else + double __fpregs[6]; +#endif + } __jmp_buf[1]; + +#endif /* _MIPS_BITS_SETJMP_H */ diff --git a/REORG.TODO/sysdeps/mips/bits/wordsize.h b/REORG.TODO/sysdeps/mips/bits/wordsize.h new file mode 100644 index 0000000000..c32e3bc491 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/bits/wordsize.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2002-2017 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/>. */ + +#include <sgidefs.h> + +#define __WORDSIZE _MIPS_SZPTR + +#if _MIPS_SIM == _ABI64 +# define __WORDSIZE_TIME64_COMPAT32 1 +#else +# define __WORDSIZE_TIME64_COMPAT32 0 +#endif + +#if __WORDSIZE == 32 +#define __WORDSIZE32_SIZE_ULONG 0 +#define __WORDSIZE32_PTRDIFF_LONG 0 +#endif diff --git a/REORG.TODO/sysdeps/mips/bsd-_setjmp.S b/REORG.TODO/sysdeps/mips/bsd-_setjmp.S new file mode 100644 index 0000000000..d5a8731227 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/bsd-_setjmp.S @@ -0,0 +1,44 @@ +/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. MIPS version. + Copyright (C) 1996-2017 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/>. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 0)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + + .set nomips16 + +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (_setjmp) +#ifdef __PIC__ + .set noreorder + .cpload t9 + .set reorder + la t9, C_SYMBOL_NAME (__sigsetjmp) +#endif + move a1,zero /* Pass a second argument of zero. */ +#ifdef __PIC__ + jr t9 +#else + j C_SYMBOL_NAME (__sigsetjmp) +#endif +END (_setjmp) +libc_hidden_def (_setjmp) diff --git a/REORG.TODO/sysdeps/mips/bsd-setjmp.S b/REORG.TODO/sysdeps/mips/bsd-setjmp.S new file mode 100644 index 0000000000..6d3d31b101 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/bsd-setjmp.S @@ -0,0 +1,43 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. MIPS version. + Copyright (C) 1996-2017 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/>. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 1)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + + .set nomips16 + +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (setjmp) + .set noreorder +#ifdef __PIC__ + .cpload t9 + .set reorder + la t9, C_SYMBOL_NAME (__sigsetjmp) +#endif + li a1, 1 /* Pass a second argument of one. */ +#ifdef __PIC__ + jr t9 +#else + j C_SYMBOL_NAME (__sigsetjmp) +#endif +END (setjmp) diff --git a/REORG.TODO/sysdeps/mips/configure b/REORG.TODO/sysdeps/mips/configure new file mode 100644 index 0000000000..4e13248c03 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/configure @@ -0,0 +1,163 @@ +# This file is generated from configure.ac by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/mips. + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler is using the 2008 NaN encoding" >&5 +$as_echo_n "checking whether the compiler is using the 2008 NaN encoding... " >&6; } +if ${libc_cv_mips_nan2008+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +dnl +#ifdef __mips_nan2008 +yes +#endif +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "yes" >/dev/null 2>&1; then : + libc_cv_mips_nan2008=yes +else + libc_cv_mips_nan2008=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_nan2008" >&5 +$as_echo "$libc_cv_mips_nan2008" >&6; } +if test x$libc_cv_mips_nan2008 = xyes; then + $as_echo "#define HAVE_MIPS_NAN2008 1" >>confdefs.h + +fi diff --git a/REORG.TODO/sysdeps/mips/configure.ac b/REORG.TODO/sysdeps/mips/configure.ac new file mode 100644 index 0000000000..bcbdaffd9f --- /dev/null +++ b/REORG.TODO/sysdeps/mips/configure.ac @@ -0,0 +1,15 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/mips. + +dnl No MIPS GCC supports accessing static and hidden symbols in an +dnl position independent way. +dnl AC_DEFINE(PI_STATIC_AND_HIDDEN) + +AC_CACHE_CHECK([whether the compiler is using the 2008 NaN encoding], + libc_cv_mips_nan2008, [AC_EGREP_CPP(yes, [dnl +#ifdef __mips_nan2008 +yes +#endif], libc_cv_mips_nan2008=yes, libc_cv_mips_nan2008=no)]) +if test x$libc_cv_mips_nan2008 = xyes; then + AC_DEFINE(HAVE_MIPS_NAN2008) +fi diff --git a/REORG.TODO/sysdeps/mips/dl-dtprocnum.h b/REORG.TODO/sysdeps/mips/dl-dtprocnum.h new file mode 100644 index 0000000000..805fbbc8f8 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/dl-dtprocnum.h @@ -0,0 +1,21 @@ +/* Configuration of lookup functions. MIPS version. + Copyright (C) 2000-2017 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/>. */ + +/* Number of extra dynamic section entries for this architecture. By + default there are none. */ +#define DT_THISPROCNUM DT_MIPS_NUM diff --git a/REORG.TODO/sysdeps/mips/dl-machine-reject-phdr.h b/REORG.TODO/sysdeps/mips/dl-machine-reject-phdr.h new file mode 100644 index 0000000000..3dde936e3b --- /dev/null +++ b/REORG.TODO/sysdeps/mips/dl-machine-reject-phdr.h @@ -0,0 +1,326 @@ +/* Machine-dependent program header inspection for the ELF loader. + Copyright (C) 2014-2017 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 _DL_MACHINE_REJECT_PHDR_H +#define _DL_MACHINE_REJECT_PHDR_H 1 + +#include <unistd.h> +#include <sys/prctl.h> + +#if defined PR_GET_FP_MODE && defined PR_SET_FP_MODE +# define HAVE_PRCTL_FP_MODE 1 +#else +# define HAVE_PRCTL_FP_MODE 0 +#endif + +/* Reject an object with a debug message. */ +#define REJECT(str, args...) \ + { \ + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) \ + _dl_debug_printf (str, ##args); \ + return true; \ + } + +/* Search the program headers for the ABI Flags. */ + +static inline const ElfW(Phdr) * +find_mips_abiflags (const ElfW(Phdr) *phdr, ElfW(Half) phnum) +{ + const ElfW(Phdr) *ph; + + for (ph = phdr; ph < &phdr[phnum]; ++ph) + if (ph->p_type == PT_MIPS_ABIFLAGS) + return ph; + return NULL; +} + +/* Cache the FP ABI value from the PT_MIPS_ABIFLAGS program header. */ + +static bool +cached_fpabi_reject_phdr_p (struct link_map *l) +{ + if (l->l_mach.fpabi == 0) + { + const ElfW(Phdr) *ph = find_mips_abiflags (l->l_phdr, l->l_phnum); + + if (ph) + { + Elf_MIPS_ABIFlags_v0 * mips_abiflags; + if (ph->p_filesz < sizeof (Elf_MIPS_ABIFlags_v0)) + REJECT (" %s: malformed PT_MIPS_ABIFLAGS found\n", l->l_name); + + mips_abiflags = (Elf_MIPS_ABIFlags_v0 *) (l->l_addr + ph->p_vaddr); + + if (__glibc_unlikely (mips_abiflags->flags2 != 0)) + REJECT (" %s: unknown MIPS.abiflags flags2: %u\n", l->l_name, + mips_abiflags->flags2); + + l->l_mach.fpabi = mips_abiflags->fp_abi; + l->l_mach.odd_spreg = (mips_abiflags->flags1 + & MIPS_AFL_FLAGS1_ODDSPREG) != 0; + } + else + { + l->l_mach.fpabi = -1; + l->l_mach.odd_spreg = true; + } + } + return false; +} + +/* Return a description of the specified floating-point ABI. */ + +static const char * +fpabi_string (int fpabi) +{ + switch (fpabi) + { + case Val_GNU_MIPS_ABI_FP_ANY: + return "Hard or soft float"; + case Val_GNU_MIPS_ABI_FP_DOUBLE: + return "Hard float (double precision)"; + case Val_GNU_MIPS_ABI_FP_SINGLE: + return "Hard float (single precision)"; + case Val_GNU_MIPS_ABI_FP_SOFT: + return "Soft float"; + case Val_GNU_MIPS_ABI_FP_OLD_64: + return "Unsupported FP64"; + case Val_GNU_MIPS_ABI_FP_XX: + return "Hard float (32-bit CPU, Any FPU)"; + case Val_GNU_MIPS_ABI_FP_64: + return "Hard float (32-bit CPU, 64-bit FPU)"; + case Val_GNU_MIPS_ABI_FP_64A: + return "Hard float compat (32-bit CPU, 64-bit FPU)"; + case -1: + return "Double precision, single precision or soft float"; + default: + return "Unknown FP ABI"; + } +} + +/* A structure to describe the requirements of each FP ABI extension. + Each field says whether the ABI can be executed in that mode. The FR0 field + is actually overloaded and means 'default' FR mode for the ABI. I.e. For + O32 it is FR0 and for N32/N64 it is actually FR1. Since this logic is + focussed on the intricacies of mode management for O32 we call the field + FR0. */ + +struct abi_req +{ + bool single; + bool soft; + bool fr0; + bool fr1; + bool fre; +}; + +/* FP ABI requirements for all Val_GNU_MIPS_ABI_FP_* values. */ + +static const struct abi_req reqs[Val_GNU_MIPS_ABI_FP_MAX + 1] = + {{true, true, true, true, true}, /* Any */ + {false, false, true, false, true}, /* Double-float */ + {true, false, false, false, false}, /* Single-float */ + {false, true, false, false, false}, /* Soft-float */ + {false, false, false, false, false}, /* old-FP64 */ + {false, false, true, true, true}, /* FPXX */ + {false, false, false, true, false}, /* FP64 */ + {false, false, false, true, true}}; /* FP64A */ + +/* FP ABI requirements for objects without a PT_MIPS_ABIFLAGS segment. */ + +static const struct abi_req none_req = { true, true, true, false, true }; + +/* Return true iff ELF program headers are incompatible with the running + host. This verifies that floating-point ABIs are compatible and + re-configures the hardware mode if necessary. This code handles both the + DT_NEEDED libraries and the dlopen'ed libraries. It also accounts for the + impact of dlclose. */ + +static bool __attribute_used__ +elf_machine_reject_phdr_p (const ElfW(Phdr) *phdr, uint_fast16_t phnum, + const char *buf, size_t len, struct link_map *map, + int fd) +{ + const ElfW(Phdr) *ph = find_mips_abiflags (phdr, phnum); + struct link_map *l; + Lmid_t nsid; + int in_abi = -1; + struct abi_req in_req; + Elf_MIPS_ABIFlags_v0 *mips_abiflags = NULL; + bool perfect_match = false; +#if _MIPS_SIM == _ABIO32 + unsigned int cur_mode = -1; +# if HAVE_PRCTL_FP_MODE + bool cannot_mode_switch = false; + + /* Get the current hardware mode. */ + cur_mode = __prctl (PR_GET_FP_MODE); +# endif +#endif + + /* Read the attributes section. */ + if (ph != NULL) + { + ElfW(Addr) size = ph->p_filesz; + + if (ph->p_offset + size <= len) + mips_abiflags = (Elf_MIPS_ABIFlags_v0 *) (buf + ph->p_offset); + else + { + mips_abiflags = alloca (size); + __lseek (fd, ph->p_offset, SEEK_SET); + if (__libc_read (fd, (void *) mips_abiflags, size) != size) + REJECT (" unable to read PT_MIPS_ABIFLAGS\n"); + } + + if (size < sizeof (Elf_MIPS_ABIFlags_v0)) + REJECT (" contains malformed PT_MIPS_ABIFLAGS\n"); + + if (__glibc_unlikely (mips_abiflags->flags2 != 0)) + REJECT (" unknown MIPS.abiflags flags2: %u\n", mips_abiflags->flags2); + + in_abi = mips_abiflags->fp_abi; + } + + /* ANY is compatible with anything. */ + perfect_match |= (in_abi == Val_GNU_MIPS_ABI_FP_ANY); + + /* Unknown ABIs are rejected. */ + if (in_abi != -1 && in_abi > Val_GNU_MIPS_ABI_FP_MAX) + REJECT (" uses unknown FP ABI: %u\n", in_abi); + + /* Obtain the initial requirements. */ + in_req = (in_abi == -1) ? none_req : reqs[in_abi]; + + /* Check that the new requirement does not conflict with any currently + loaded object. */ + for (nsid = 0; nsid < DL_NNS; ++nsid) + for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next) + { + struct abi_req existing_req; + + if (cached_fpabi_reject_phdr_p (l)) + return true; + +#if _MIPS_SIM == _ABIO32 + /* A special case arises for O32 FP64 and FP64A where the kernel + pre-dates PT_MIPS_ABIFLAGS. These ABIs will be blindly loaded even + if the hardware mode is unavailable or disabled. In this + circumstance the prctl call to obtain the current mode will fail. + Detect this situation here and reject everything. This will + effectively prevent dynamically linked applications from failing in + unusual ways but there is nothing we can do to help static + applications. */ + if ((l->l_mach.fpabi == Val_GNU_MIPS_ABI_FP_64A + || l->l_mach.fpabi == Val_GNU_MIPS_ABI_FP_64) + && cur_mode == -1) + REJECT (" found %s running in the wrong mode\n", + fpabi_string (l->l_mach.fpabi)); +#endif + + /* Found a perfect match, success. */ + perfect_match |= (in_abi == l->l_mach.fpabi); + + /* Unknown ABIs are rejected. */ + if (l->l_mach.fpabi != -1 && l->l_mach.fpabi > Val_GNU_MIPS_ABI_FP_MAX) + REJECT (" found unknown FP ABI: %u\n", l->l_mach.fpabi); + + existing_req = (l->l_mach.fpabi == -1 ? none_req + : reqs[l->l_mach.fpabi]); + + /* Merge requirements. */ + in_req.soft &= existing_req.soft; + in_req.single &= existing_req.single; + in_req.fr0 &= existing_req.fr0; + in_req.fr1 &= existing_req.fr1; + in_req.fre &= existing_req.fre; + + /* If there is at least one mode which is still usable then the new + object can be loaded. */ + if (in_req.single || in_req.soft || in_req.fr1 || in_req.fr0 + || in_req.fre) + { +#if _MIPS_SIM == _ABIO32 && HAVE_PRCTL_FP_MODE + /* Account for loaded ABIs which prohibit mode switching. */ + if (l->l_mach.fpabi == Val_GNU_MIPS_ABI_FP_XX) + cannot_mode_switch |= l->l_mach.odd_spreg; +#endif + } + else + REJECT (" uses %s, already loaded %s\n", + fpabi_string (in_abi), + fpabi_string (l->l_mach.fpabi)); + } + +#if _MIPS_SIM == _ABIO32 + /* At this point we know that the newly loaded object is compatible with all + existing objects but the hardware mode may not be correct. */ + if ((in_req.fr1 || in_req.fre || in_req.fr0) + && !perfect_match) + { + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) + _dl_debug_printf (" needs %s%s mode\n", in_req.fr0 ? "FR0 or " : "", + (in_req.fre && !in_req.fr1) ? "FRE" : "FR1"); + + /* If the PR_GET_FP_MODE is not supported then only FR0 is available. + If the overall requirements cannot be met by FR0 then reject the + object. */ + if (cur_mode == -1) + return !in_req.fr0; + +# if HAVE_PRCTL_FP_MODE + { + unsigned int fr1_mode = PR_FP_MODE_FR; + + /* It is not possible to change the mode of a thread which may be + executing FPXX code with odd-singles. If an FPXX object with + odd-singles is loaded then just check the current mode is OK. This + can be either the FR1 mode or FR0 if the requirements are met by + FR0. */ + if (cannot_mode_switch) + return (!(in_req.fre && cur_mode == (PR_FP_MODE_FR | PR_FP_MODE_FRE)) + && !(in_req.fr1 && cur_mode == PR_FP_MODE_FR) + && !(in_req.fr0 && cur_mode == 0)); + + /* If the overall requirements can be satisfied by FRE but not FR1 then + fr1_mode must become FRE. */ + if (in_req.fre && !in_req.fr1) + fr1_mode |= PR_FP_MODE_FRE; + + /* Set the new mode. Use fr1_mode if the requirements cannot be met by + FR0. */ + if (!in_req.fr0) + return __prctl (PR_SET_FP_MODE, fr1_mode) != 0; + else if (__prctl (PR_SET_FP_MODE, /* fr0_mode */ 0) != 0) + { + /* Setting FR0 can validly fail on an R6 core so retry with the FR1 + mode as a fall back. */ + if (errno != ENOTSUP) + return true; + + return __prctl (PR_SET_FP_MODE, fr1_mode) != 0; + } + } +# endif /* HAVE_PRCTL_FP_MODE */ + } +#endif /* _MIPS_SIM == _ABIO32 */ + + return false; +} + +#endif /* dl-machine-reject-phdr.h */ diff --git a/REORG.TODO/sysdeps/mips/dl-machine.h b/REORG.TODO/sysdeps/mips/dl-machine.h new file mode 100644 index 0000000000..ed47513ccc --- /dev/null +++ b/REORG.TODO/sysdeps/mips/dl-machine.h @@ -0,0 +1,936 @@ +/* Machine-dependent ELF dynamic relocation inline functions. MIPS version. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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/>. */ + +/* FIXME: Profiling of shared libraries is not implemented yet. */ +#ifndef dl_machine_h +#define dl_machine_h + +#define ELF_MACHINE_NAME "MIPS" + +#include <entry.h> + +#ifndef ENTRY_POINT +#error ENTRY_POINT needs to be defined for MIPS. +#endif + +#include <sgidefs.h> +#include <sysdep.h> +#include <sys/asm.h> +#include <dl-tls.h> + +/* The offset of gp from GOT might be system-dependent. It's set by + ld. The same value is also */ +#define OFFSET_GP_GOT 0x7ff0 + +#ifndef _RTLD_PROLOGUE +# define _RTLD_PROLOGUE(entry) \ + ".globl\t" __STRING(entry) "\n\t" \ + ".ent\t" __STRING(entry) "\n\t" \ + ".type\t" __STRING(entry) ", @function\n" \ + __STRING(entry) ":\n\t" +#endif + +#ifndef _RTLD_EPILOGUE +# define _RTLD_EPILOGUE(entry) \ + ".end\t" __STRING(entry) "\n\t" \ + ".size\t" __STRING(entry) ", . - " __STRING(entry) "\n\t" +#endif + +/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. + This only makes sense on MIPS when using PLTs, so choose the + PLT relocation (not encountered when not using PLTs). */ +#define ELF_MACHINE_JMP_SLOT R_MIPS_JUMP_SLOT +#define elf_machine_type_class(type) \ + ((((type) == ELF_MACHINE_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_MIPS_COPY) * ELF_RTYPE_CLASS_COPY)) + +#define ELF_MACHINE_PLT_REL 1 +#define ELF_MACHINE_NO_REL 0 +#define ELF_MACHINE_NO_RELA 0 + +/* Translate a processor specific dynamic tag to the index + in l_info array. */ +#define DT_MIPS(x) (DT_MIPS_##x - DT_LOPROC + DT_NUM) + +/* If there is a DT_MIPS_RLD_MAP_REL or DT_MIPS_RLD_MAP entry in the dynamic + section, fill in the debug map pointer with the run-time address of the + r_debug structure. */ +#define ELF_MACHINE_DEBUG_SETUP(l,r) \ +do { if ((l)->l_info[DT_MIPS (RLD_MAP_REL)]) \ + { \ + char *ptr = (char *)(l)->l_info[DT_MIPS (RLD_MAP_REL)]; \ + ptr += (l)->l_info[DT_MIPS (RLD_MAP_REL)]->d_un.d_val; \ + *(ElfW(Addr) *)ptr = (ElfW(Addr)) (r); \ + } \ + else if ((l)->l_info[DT_MIPS (RLD_MAP)]) \ + *(ElfW(Addr) *)((l)->l_info[DT_MIPS (RLD_MAP)]->d_un.d_ptr) = \ + (ElfW(Addr)) (r); \ + } while (0) + +#if ((defined __mips_nan2008 && !defined HAVE_MIPS_NAN2008) \ + || (!defined __mips_nan2008 && defined HAVE_MIPS_NAN2008)) +# error "Configuration inconsistency: __mips_nan2008 != HAVE_MIPS_NAN2008, overridden CFLAGS?" +#endif +#ifdef __mips_nan2008 +# define ELF_MACHINE_NAN2008 EF_MIPS_NAN2008 +#else +# define ELF_MACHINE_NAN2008 0 +#endif + +/* Return nonzero iff ELF header is compatible with the running host. */ +static inline int __attribute_used__ +elf_machine_matches_host (const ElfW(Ehdr) *ehdr) +{ +#if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32 + /* Don't link o32 and n32 together. */ + if (((ehdr->e_flags & EF_MIPS_ABI2) != 0) != (_MIPS_SIM == _ABIN32)) + return 0; +#endif + + /* Don't link 2008-NaN and legacy-NaN objects together. */ + if ((ehdr->e_flags & EF_MIPS_NAN2008) != ELF_MACHINE_NAN2008) + return 0; + + /* Ensure that the old O32 FP64 ABI is never loaded, it is not supported + on linux. */ + if (ehdr->e_flags & EF_MIPS_FP64) + return 0; + + switch (ehdr->e_machine) + { + case EM_MIPS: + case EM_MIPS_RS3_LE: + return 1; + default: + return 0; + } +} + +static inline ElfW(Addr) * +elf_mips_got_from_gpreg (ElfW(Addr) gpreg) +{ + /* FIXME: the offset of gp from GOT may be system-dependent. */ + return (ElfW(Addr) *) (gpreg - OFFSET_GP_GOT); +} + +/* 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. We assume its $gp points to the primary GOT. */ +static inline ElfW(Addr) +elf_machine_dynamic (void) +{ + register ElfW(Addr) gp __asm__ ("$28"); + return *elf_mips_got_from_gpreg (gp); +} + +#define STRINGXP(X) __STRING(X) +#define STRINGXV(X) STRINGV_(X) +#define STRINGV_(...) # __VA_ARGS__ + +/* Return the run-time load address of the shared object. */ +static inline ElfW(Addr) +elf_machine_load_address (void) +{ + ElfW(Addr) addr; +#ifndef __mips16 + asm (" .set noreorder\n" + " " STRINGXP (PTR_LA) " %0, 0f\n" +# if !defined __mips_isa_rev || __mips_isa_rev < 6 + " bltzal $0, 0f\n" + " nop\n" + "0: " STRINGXP (PTR_SUBU) " %0, $31, %0\n" +# else + "0: addiupc $31, 0\n" + " " STRINGXP (PTR_SUBU) " %0, $31, %0\n" +# endif + " .set reorder\n" + : "=r" (addr) + : /* No inputs */ + : "$31"); +#else + ElfW(Addr) tmp; + asm (" .set noreorder\n" + " move %1,$gp\n" + " lw %1,%%got(0f)(%1)\n" + "0: .fill 0\n" /* Clear the ISA bit on 0:. */ + " la %0,0b\n" + " addiu %1,%%lo(0b)\n" + " subu %0,%1\n" + " .set reorder\n" + : "=d" (addr), "=d" (tmp) + : /* No inputs */); +#endif + return addr; +} + +/* The MSB of got[1] of a gnu object is set to identify gnu objects. */ +#if _MIPS_SIM == _ABI64 +# define ELF_MIPS_GNU_GOT1_MASK 0x8000000000000000L +#else +# define ELF_MIPS_GNU_GOT1_MASK 0x80000000L +#endif + +/* We can't rely on elf_machine_got_rel because _dl_object_relocation_scope + fiddles with global data. */ +#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \ +do { \ + struct link_map *map = &bootstrap_map; \ + ElfW(Sym) *sym; \ + ElfW(Addr) *got; \ + int i, n; \ + \ + got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]); \ + \ + if (__builtin_expect (map->l_addr == 0, 1)) \ + break; \ + \ + /* got[0] is reserved. got[1] is also reserved for the dynamic object \ + generated by gnu ld. Skip these reserved entries from \ + relocation. */ \ + i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1; \ + n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val; \ + \ + /* Add the run-time displacement to all local got entries. */ \ + while (i < n) \ + got[i++] += map->l_addr; \ + \ + /* Handle global got entries. */ \ + got += n; \ + sym = (ElfW(Sym) *) D_PTR(map, l_info[DT_SYMTAB]) \ + + map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val; \ + i = (map->l_info[DT_MIPS (SYMTABNO)]->d_un.d_val \ + - map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val); \ + \ + while (i--) \ + { \ + if (sym->st_shndx == SHN_UNDEF || sym->st_shndx == SHN_COMMON) \ + *got = map->l_addr + sym->st_value; \ + else if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC \ + && *got != sym->st_value) \ + *got += map->l_addr; \ + else if (ELFW(ST_TYPE) (sym->st_info) == STT_SECTION) \ + { \ + if (sym->st_other == 0) \ + *got += map->l_addr; \ + } \ + else \ + *got = map->l_addr + sym->st_value; \ + \ + got++; \ + sym++; \ + } \ +} while(0) + + +/* Mask identifying addresses reserved for the user program, + where the dynamic linker should not map anything. */ +#define ELF_MACHINE_USER_ADDRESS_MASK 0x80000000UL + + +/* Initial entry point code for the dynamic linker. + The C function `_dl_start' is the real entry point; + its return value is the user program's entry point. + Note how we have to be careful about two things: + + 1) That we allocate a minimal stack of 24 bytes for + every function call, the MIPS ABI states that even + if all arguments are passed in registers the procedure + called can use the 16 byte area pointed to by $sp + when it is called to store away the arguments passed + to it. + + 2) That under Unix the entry is named __start + and not just plain _start. */ + +#ifndef __mips16 +# if !defined __mips_isa_rev || __mips_isa_rev < 6 +# define LCOFF STRINGXP(.Lcof2) +# define LOAD_31 STRINGXP(bltzal $8) "," STRINGXP(.Lcof2) +# else +# define LCOFF STRINGXP(.Lcof1) +# define LOAD_31 "addiupc $31, 0" +# endif +# define RTLD_START asm (\ + ".text\n\ + " _RTLD_PROLOGUE(ENTRY_POINT) "\ + " STRINGXV(SETUP_GPX($25)) "\n\ + " STRINGXV(SETUP_GPX64($18,$25)) "\n\ + # i386 ABI book says that the first entry of GOT holds\n\ + # the address of the dynamic structure. Though MIPS ABI\n\ + # doesn't say nothing about this, I emulate this here.\n\ + " STRINGXP(PTR_LA) " $4, _DYNAMIC\n\ + # Subtract OFFSET_GP_GOT\n\ + " STRINGXP(PTR_S) " $4, -0x7ff0($28)\n\ + move $4, $29\n\ + " STRINGXP(PTR_SUBIU) " $29, 16\n\ + \n\ + " STRINGXP(PTR_LA) " $8, " LCOFF "\n\ +.Lcof1: " LOAD_31 "\n\ +.Lcof2: " STRINGXP(PTR_SUBU) " $8, $31, $8\n\ + \n\ + " STRINGXP(PTR_LA) " $25, _dl_start\n\ + " STRINGXP(PTR_ADDU) " $25, $8\n\ + jalr $25\n\ + \n\ + " STRINGXP(PTR_ADDIU) " $29, 16\n\ + # Get the value of label '_dl_start_user' in t9 ($25).\n\ + " STRINGXP(PTR_LA) " $25, _dl_start_user\n\ + " _RTLD_EPILOGUE(ENTRY_POINT) "\ + \n\ + \n\ + " _RTLD_PROLOGUE(_dl_start_user) "\ + " STRINGXP(SETUP_GP) "\n\ + " STRINGXV(SETUP_GP64($18,_dl_start_user)) "\n\ + move $16, $28\n\ + # Save the user entry point address in a saved register.\n\ + move $17, $2\n\ + # See if we were run as a command with the executable file\n\ + # name as an extra leading argument.\n\ + lw $2, _dl_skip_args\n\ + beq $2, $0, 1f\n\ + # Load the original argument count.\n\ + " STRINGXP(PTR_L) " $4, 0($29)\n\ + # Subtract _dl_skip_args from it.\n\ + subu $4, $2\n\ + # Adjust the stack pointer to skip _dl_skip_args words.\n\ + sll $2, " STRINGXP (PTRLOG) "\n\ + " STRINGXP(PTR_ADDU) " $29, $2\n\ + # Save back the modified argument count.\n\ + " STRINGXP(PTR_S) " $4, 0($29)\n\ +1: # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env) \n\ + " STRINGXP(PTR_L) " $4, _rtld_local\n\ + " STRINGXP(PTR_L) /* or lw??? fixme */ " $5, 0($29)\n\ + " STRINGXP(PTR_LA) " $6, " STRINGXP (PTRSIZE) "($29)\n\ + sll $7, $5, " STRINGXP (PTRLOG) "\n\ + " STRINGXP(PTR_ADDU) " $7, $7, $6\n\ + " STRINGXP(PTR_ADDU) " $7, $7, " STRINGXP (PTRSIZE) " \n\ + # Make sure the stack pointer is aligned for _dl_init.\n\ + and $2, $29, -2 * " STRINGXP(SZREG) "\n\ + move $8, $29\n\ + " STRINGXP(PTR_SUBIU) " $29, $2, 32\n\ + " STRINGXP(PTR_S) " $8, (32 - " STRINGXP(SZREG) ")($29)\n\ + " STRINGXP(SAVE_GP(16)) "\n\ + # Call the function to run the initializers.\n\ + jal _dl_init\n\ + # Restore the stack pointer for _start.\n\ + " STRINGXP(PTR_L) " $29, (32 - " STRINGXP(SZREG) ")($29)\n\ + # Pass our finalizer function to the user in $2 as per ELF ABI.\n\ + " STRINGXP(PTR_LA) " $2, _dl_fini\n\ + # Jump to the user entry point.\n\ + move $25, $17\n\ + jr $25\n\t"\ + _RTLD_EPILOGUE(_dl_start_user)\ + ".previous"\ +); + +#else /* __mips16 */ +/* MIPS16 version. We currently only support O32 under MIPS16; the proper + assembly preprocessor abstractions will need to be added if other ABIs + are to be supported. */ + +# define RTLD_START asm (\ + ".text\n\ + .set mips16\n\ + " _RTLD_PROLOGUE (ENTRY_POINT) "\ + # Construct GP value in $3.\n\ + li $3, %hi(_gp_disp)\n\ + addiu $4, $pc, %lo(_gp_disp)\n\ + sll $3, 16\n\ + addu $3, $4\n\ + move $28, $3\n\ + lw $4, %got(_DYNAMIC)($3)\n\ + sw $4, -0x7ff0($3)\n\ + move $4, $sp\n\ + addiu $sp, -16\n\ + # _dl_start() is sufficiently near to use pc-relative\n\ + # load address.\n\ + la $3, _dl_start\n\ + move $25, $3\n\ + jalr $3\n\ + addiu $sp, 16\n\ + " _RTLD_EPILOGUE (ENTRY_POINT) "\ + \n\ + \n\ + " _RTLD_PROLOGUE (_dl_start_user) "\ + li $16, %hi(_gp_disp)\n\ + addiu $4, $pc, %lo(_gp_disp)\n\ + sll $16, 16\n\ + addu $16, $4\n\ + move $17, $2\n\ + move $28, $16\n\ + lw $4, %got(_dl_skip_args)($16)\n\ + lw $4, 0($4)\n\ + beqz $4, 1f\n\ + # Load the original argument count.\n\ + lw $5, 0($sp)\n\ + # Subtract _dl_skip_args from it.\n\ + subu $5, $4\n\ + # Adjust the stack pointer to skip _dl_skip_args words.\n\ + sll $4, " STRINGXP (PTRLOG) "\n\ + move $6, $sp\n\ + addu $6, $4\n\ + move $sp, $6\n\ + # Save back the modified argument count.\n\ + sw $5, 0($sp)\n\ +1: # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env) \n\ + lw $4, %got(_rtld_local)($16)\n\ + lw $4, 0($4)\n\ + lw $5, 0($sp)\n\ + addiu $6, $sp, " STRINGXP (PTRSIZE) "\n\ + sll $7, $5, " STRINGXP (PTRLOG) "\n\ + addu $7, $6\n\ + addu $7, " STRINGXP (PTRSIZE) "\n\ + # Make sure the stack pointer is aligned for _dl_init.\n\ + li $2, 2 * " STRINGXP (SZREG) "\n\ + neg $2, $2\n\ + move $3, $sp\n\ + and $2, $3\n\ + sw $3, -" STRINGXP (SZREG) "($2)\n\ + addiu $2, -32\n\ + move $sp, $2\n\ + sw $16, 16($sp)\n\ + # Call the function to run the initializers.\n\ + lw $2, %call16(_dl_init)($16)\n\ + move $25, $2\n\ + jalr $2\n\ + # Restore the stack pointer for _start.\n\ + lw $2, 32-" STRINGXP (SZREG) "($sp)\n\ + move $sp, $2\n\ + move $28, $16\n\ + # Pass our finalizer function to the user in $2 as per ELF ABI.\n\ + lw $2, %call16(_dl_fini)($16)\n\ + # Jump to the user entry point.\n\ + move $25, $17\n\ + jr $17\n\t"\ + _RTLD_EPILOGUE (_dl_start_user)\ + ".previous"\ +); + +#endif /* __mips16 */ + +/* Names of the architecture-specific auditing callback functions. */ +# if _MIPS_SIM == _ABIO32 +# define ARCH_LA_PLTENTER mips_o32_gnu_pltenter +# define ARCH_LA_PLTEXIT mips_o32_gnu_pltexit +# elif _MIPS_SIM == _ABIN32 +# define ARCH_LA_PLTENTER mips_n32_gnu_pltenter +# define ARCH_LA_PLTEXIT mips_n32_gnu_pltexit +# else +# define ARCH_LA_PLTENTER mips_n64_gnu_pltenter +# define ARCH_LA_PLTEXIT mips_n64_gnu_pltexit +# endif + +/* We define an initialization function. This is called very early in + _dl_sysdep_start. */ +#define DL_PLATFORM_INIT dl_platform_init () + +static inline void __attribute__ ((unused)) +dl_platform_init (void) +{ + if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0') + /* Avoid an empty string which would disturb us. */ + GLRO(dl_platform) = NULL; +} + +/* For a non-writable PLT, rewrite the .got.plt entry at RELOC_ADDR to + point at the symbol with address VALUE. For a writable PLT, rewrite + the corresponding PLT entry instead. */ +static inline ElfW(Addr) +elf_machine_fixup_plt (struct link_map *map, lookup_t t, + const ElfW(Rel) *reloc, + ElfW(Addr) *reloc_addr, ElfW(Addr) value) +{ + return *reloc_addr = value; +} + +static inline ElfW(Addr) +elf_machine_plt_value (struct link_map *map, const ElfW(Rel) *reloc, + ElfW(Addr) value) +{ + return value; +} + +/* The semantics of zero/non-zero values of undefined symbols differs + depending on whether the non-PIC ABI is in use. Under the non-PIC + ABI, a non-zero value indicates that there is an address reference + to the symbol and thus it must always be resolved (except when + resolving a jump slot relocation) to the PLT entry whose address is + provided as the symbol's value; a zero value indicates that this + canonical-address behaviour is not required. Yet under the classic + MIPS psABI, a zero value indicates that there is an address + reference to the function and the dynamic linker must resolve the + symbol immediately upon loading. To avoid conflict, symbols for + which the dynamic linker must assume the non-PIC ABI semantics are + marked with the STO_MIPS_PLT flag. */ +#define ELF_MACHINE_SYM_NO_MATCH(sym) \ + ((sym)->st_shndx == SHN_UNDEF && !((sym)->st_other & STO_MIPS_PLT)) + +#endif /* !dl_machine_h */ + +#ifdef RESOLVE_MAP + +/* Perform a relocation described by R_INFO at the location pointed to + by RELOC_ADDR. SYM is the relocation symbol specified by R_INFO and + MAP is the object containing the reloc. */ + +auto inline void +__attribute__ ((always_inline)) +elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info, + const ElfW(Sym) *sym, const struct r_found_version *version, + void *reloc_addr, ElfW(Addr) r_addend, int inplace_p) +{ + const unsigned long int r_type = ELFW(R_TYPE) (r_info); + ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr; + +#if !defined RTLD_BOOTSTRAP && !defined SHARED + /* This is defined in rtld.c, but nowhere in the static libc.a; + make the reference weak so static programs can still link. This + declaration cannot be done when compiling rtld.c (i.e. #ifdef + RTLD_BOOTSTRAP) because rtld.c contains the common defn for + _dl_rtld_map, which is incompatible with a weak decl in the same + file. */ + weak_extern (GL(dl_rtld_map)); +#endif + + switch (r_type) + { +#if !defined (RTLD_BOOTSTRAP) +# if _MIPS_SIM == _ABI64 + case R_MIPS_TLS_DTPMOD64: + case R_MIPS_TLS_DTPREL64: + case R_MIPS_TLS_TPREL64: +# else + case R_MIPS_TLS_DTPMOD32: + case R_MIPS_TLS_DTPREL32: + case R_MIPS_TLS_TPREL32: +# endif + { + struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); + + switch (r_type) + { + case R_MIPS_TLS_DTPMOD64: + case R_MIPS_TLS_DTPMOD32: + if (sym_map) + *addr_field = sym_map->l_tls_modid; + break; + + case R_MIPS_TLS_DTPREL64: + case R_MIPS_TLS_DTPREL32: + if (sym) + { + if (inplace_p) + r_addend = *addr_field; + *addr_field = r_addend + TLS_DTPREL_VALUE (sym); + } + break; + + case R_MIPS_TLS_TPREL32: + case R_MIPS_TLS_TPREL64: + if (sym) + { + CHECK_STATIC_TLS (map, sym_map); + if (inplace_p) + r_addend = *addr_field; + *addr_field = r_addend + TLS_TPREL_VALUE (sym_map, sym); + } + break; + } + + break; + } +#endif + +#if _MIPS_SIM == _ABI64 + case (R_MIPS_64 << 8) | R_MIPS_REL32: +#else + case R_MIPS_REL32: +#endif + { + int symidx = ELFW(R_SYM) (r_info); + ElfW(Addr) reloc_value; + + if (inplace_p) + /* Support relocations on mis-aligned offsets. */ + __builtin_memcpy (&reloc_value, reloc_addr, sizeof (reloc_value)); + else + reloc_value = r_addend; + + if (symidx) + { + const ElfW(Word) gotsym + = (const ElfW(Word)) map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val; + + if ((ElfW(Word))symidx < gotsym) + { + /* This wouldn't work for a symbol imported from other + libraries for which there's no GOT entry, but MIPS + requires every symbol referenced in a dynamic + relocation to have a GOT entry in the primary GOT, + so we only get here for locally-defined symbols. + For section symbols, we should *NOT* be adding + sym->st_value (per the definition of the meaning of + S in reloc expressions in the ELF64 MIPS ABI), + since it should have already been added to + reloc_value by the linker, but older versions of + GNU ld didn't add it, and newer versions don't emit + useless relocations to section symbols any more, so + it is safe to keep on adding sym->st_value, even + though it's not ABI compliant. Some day we should + bite the bullet and stop doing this. */ +#ifndef RTLD_BOOTSTRAP + if (map != &GL(dl_rtld_map)) +#endif + reloc_value += sym->st_value + map->l_addr; + } + else + { +#ifndef RTLD_BOOTSTRAP + const ElfW(Addr) *got + = (const ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]); + const ElfW(Word) local_gotno + = (const ElfW(Word)) + map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val; + + reloc_value += got[symidx + local_gotno - gotsym]; +#endif + } + } + else +#ifndef RTLD_BOOTSTRAP + if (map != &GL(dl_rtld_map)) +#endif + reloc_value += map->l_addr; + + __builtin_memcpy (reloc_addr, &reloc_value, sizeof (reloc_value)); + } + break; +#ifndef RTLD_BOOTSTRAP +#if _MIPS_SIM == _ABI64 + case (R_MIPS_64 << 8) | R_MIPS_GLOB_DAT: +#else + case R_MIPS_GLOB_DAT: +#endif + { + int symidx = ELFW(R_SYM) (r_info); + const ElfW(Word) gotsym + = (const ElfW(Word)) map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val; + + if (__builtin_expect ((ElfW(Word)) symidx >= gotsym, 1)) + { + const ElfW(Addr) *got + = (const ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]); + const ElfW(Word) local_gotno + = ((const ElfW(Word)) + map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val); + + ElfW(Addr) reloc_value = got[symidx + local_gotno - gotsym]; + __builtin_memcpy (reloc_addr, &reloc_value, sizeof (reloc_value)); + } + } + break; +#endif + case R_MIPS_NONE: /* Alright, Wilbur. */ + break; + + case R_MIPS_JUMP_SLOT: + { + struct link_map *sym_map; + ElfW(Addr) value; + + /* The addend for a jump slot relocation must always be zero: + calls via the PLT always branch to the symbol's address and + not to the address plus a non-zero offset. */ + if (r_addend != 0) + _dl_signal_error (0, map->l_name, NULL, + "found jump slot relocation with non-zero addend"); + + sym_map = RESOLVE_MAP (&sym, version, r_type); + value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value; + *addr_field = value; + + break; + } + + case R_MIPS_COPY: + { + const ElfW(Sym) *const refsym = sym; + struct link_map *sym_map; + ElfW(Addr) value; + + /* Calculate the address of the symbol. */ + sym_map = RESOLVE_MAP (&sym, version, r_type); + value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value; + + if (__builtin_expect (sym == NULL, 0)) + /* This can happen in trace mode if an object could not be + found. */ + break; + if (__builtin_expect (sym->st_size > refsym->st_size, 0) + || (__builtin_expect (sym->st_size < refsym->st_size, 0) + && GLRO(dl_verbose))) + { + const char *strtab; + + strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); + _dl_error_printf ("\ + %s: Symbol `%s' has different size in shared object, consider re-linking\n", + RTLD_PROGNAME, strtab + refsym->st_name); + } + memcpy (reloc_addr, (void *) value, + MIN (sym->st_size, refsym->st_size)); + break; + } + +#if _MIPS_SIM == _ABI64 + case R_MIPS_64: + /* For full compliance with the ELF64 ABI, one must precede the + _REL32/_64 pair of relocations with a _64 relocation, such + that the in-place addend is read as a 64-bit value. IRIX + didn't pick up on this requirement, so we treat the + _REL32/_64 relocation as a 64-bit relocation even if it's by + itself. For ABI compliance, we ignore such _64 dummy + relocations. For RELA, this may be simply removed, since + it's totally unnecessary. */ + if (ELFW(R_SYM) (r_info) == 0) + break; + /* Fall through. */ +#endif + default: + _dl_reloc_bad_type (map, r_type, 0); + break; + } +} + +/* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +auto inline void +__attribute__ ((always_inline)) +elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc, + const ElfW(Sym) *sym, const struct r_found_version *version, + void *const reloc_addr, int skip_ifunc) +{ + elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr, 0, 1); +} + +auto inline void +__attribute__((always_inline)) +elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc, + void *const reloc_addr) +{ + /* XXX Nothing to do. There is no relative relocation, right? */ +} + +auto inline void +__attribute__((always_inline)) +elf_machine_lazy_rel (struct link_map *map, + ElfW(Addr) l_addr, const ElfW(Rel) *reloc, + int skip_ifunc) +{ + ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned int r_type = ELFW(R_TYPE) (reloc->r_info); + /* Check for unexpected PLT reloc type. */ + if (__builtin_expect (r_type == R_MIPS_JUMP_SLOT, 1)) + { + if (__builtin_expect (map->l_mach.plt, 0) == 0) + { + /* Nothing is required here since we only support lazy + relocation in executables. */ + } + else + *reloc_addr = map->l_mach.plt; + } + else + _dl_reloc_bad_type (map, r_type, 1); +} + +auto inline void +__attribute__ ((always_inline)) +elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, + const ElfW(Sym) *sym, const struct r_found_version *version, + void *const reloc_addr, int skip_ifunc) +{ + elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr, + reloc->r_addend, 0); +} + +auto inline void +__attribute__((always_inline)) +elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + void *const reloc_addr) +{ +} + +#ifndef RTLD_BOOTSTRAP +/* Relocate GOT. */ +auto inline void +__attribute__((always_inline)) +elf_machine_got_rel (struct link_map *map, int lazy) +{ + ElfW(Addr) *got; + ElfW(Sym) *sym; + const ElfW(Half) *vernum; + int i, n, symidx; + +#define RESOLVE_GOTSYM(sym,vernum,sym_index,reloc) \ + ({ \ + const ElfW(Sym) *ref = sym; \ + const struct r_found_version *version __attribute__ ((unused)) \ + = vernum ? &map->l_versions[vernum[sym_index] & 0x7fff] : NULL; \ + struct link_map *sym_map; \ + sym_map = RESOLVE_MAP (&ref, version, reloc); \ + ref ? sym_map->l_addr + ref->st_value : 0; \ + }) + + if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL) + vernum = (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); + else + vernum = NULL; + + got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]); + + n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val; + /* The dynamic linker's local got entries have already been relocated. */ + if (map != &GL(dl_rtld_map)) + { + /* got[0] is reserved. got[1] is also reserved for the dynamic object + generated by gnu ld. Skip these reserved entries from relocation. */ + i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1; + + /* Add the run-time displacement to all local got entries if + needed. */ + if (__builtin_expect (map->l_addr != 0, 0)) + { + while (i < n) + got[i++] += map->l_addr; + } + } + + /* Handle global got entries. */ + got += n; + /* Keep track of the symbol index. */ + symidx = map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val; + sym = (ElfW(Sym) *) D_PTR (map, l_info[DT_SYMTAB]) + symidx; + i = (map->l_info[DT_MIPS (SYMTABNO)]->d_un.d_val + - map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val); + + /* This loop doesn't handle Quickstart. */ + while (i--) + { + if (sym->st_shndx == SHN_UNDEF) + { + if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC && sym->st_value + && !(sym->st_other & STO_MIPS_PLT)) + { + if (lazy) + *got = sym->st_value + map->l_addr; + else + /* This is a lazy-binding stub, so we don't need the + canonical address. */ + *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_JUMP_SLOT); + } + else + *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_32); + } + else if (sym->st_shndx == SHN_COMMON) + *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_32); + else if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC + && *got != sym->st_value) + { + if (lazy) + *got += map->l_addr; + else + /* This is a lazy-binding stub, so we don't need the + canonical address. */ + *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_JUMP_SLOT); + } + else if (ELFW(ST_TYPE) (sym->st_info) == STT_SECTION) + { + if (sym->st_other == 0) + *got += map->l_addr; + } + else + *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_32); + + ++got; + ++sym; + ++symidx; + } + +#undef RESOLVE_GOTSYM +} +#endif + +/* Set up the loaded object described by L so its stub function + will jump to the on-demand fixup code __dl_runtime_resolve. */ + +auto inline int +__attribute__((always_inline)) +elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) +{ +# ifndef RTLD_BOOTSTRAP + ElfW(Addr) *got; + extern void _dl_runtime_resolve (ElfW(Word)); + extern void _dl_runtime_pltresolve (void); + extern int _dl_mips_gnu_objects; + + if (lazy) + { + /* The GOT entries for functions have not yet been filled in. + Their initial contents will arrange when called to put an + offset into the .dynsym section in t8, the return address + in t7 and then jump to _GLOBAL_OFFSET_TABLE[0]. */ + got = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]); + + /* This function will get called to fix up the GOT entry indicated by + the register t8, and then jump to the resolved address. */ + got[0] = (ElfW(Addr)) &_dl_runtime_resolve; + + /* Store l to _GLOBAL_OFFSET_TABLE[1] for gnu object. The MSB + of got[1] of a gnu object is set to identify gnu objects. + Where we can store l for non gnu objects? XXX */ + if ((got[1] & ELF_MIPS_GNU_GOT1_MASK) != 0) + got[1] = ((ElfW(Addr)) l | ELF_MIPS_GNU_GOT1_MASK); + else + _dl_mips_gnu_objects = 0; + } + + /* Relocate global offset table. */ + elf_machine_got_rel (l, lazy); + + /* If using PLTs, fill in the first two entries of .got.plt. */ + if (l->l_info[DT_JMPREL] && lazy) + { + ElfW(Addr) *gotplt; + gotplt = (ElfW(Addr) *) D_PTR (l, l_info[DT_MIPS (PLTGOT)]); + /* If a library is prelinked but we have to relocate anyway, + we have to be able to undo the prelinking of .got.plt. + The prelinker saved the address of .plt for us here. */ + if (gotplt[1]) + l->l_mach.plt = gotplt[1] + l->l_addr; + gotplt[0] = (ElfW(Addr)) &_dl_runtime_pltresolve; + gotplt[1] = (ElfW(Addr)) l; + } + +# endif + return lazy; +} + +#endif /* RESOLVE_MAP */ diff --git a/REORG.TODO/sysdeps/mips/dl-procinfo.c b/REORG.TODO/sysdeps/mips/dl-procinfo.c new file mode 100644 index 0000000000..a3e0703794 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/dl-procinfo.c @@ -0,0 +1,63 @@ +/* Data for Mips version of processor capability information. + Copyright (C) 2007-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Robert Millan <rmh@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, see + <http://www.gnu.org/licenses/>. */ + +/* This information must be kept in sync with the _DL_PLATFORM_COUNT + definitions in procinfo.h. + + If anything should be added here check whether the size of each string + is still ok with the given array size. + + All the #ifdefs in the definitions are quite irritating but + necessary if we want to avoid duplicating the information. There + are three different modes: + + - PROCINFO_DECL is defined. This means we are only interested in + declarations. + + - PROCINFO_DECL is not defined: + + + if SHARED is defined the file is included in an array + initializer. The .element = { ... } syntax is needed. + + + if SHARED is not defined a normal array initialization is + needed. + */ + +#ifndef PROCINFO_CLASS +#define PROCINFO_CLASS +#endif + +#if !defined PROCINFO_DECL && defined SHARED + ._dl_mips_platforms +#else +PROCINFO_CLASS const char _dl_mips_platforms[4][11] +#endif +#ifndef PROCINFO_DECL += { + "loongson2e", "loongson2f", "octeon", "octeon2" + } +#endif +#if !defined SHARED || defined PROCINFO_DECL +; +#else +, +#endif + +#undef PROCINFO_DECL +#undef PROCINFO_CLASS diff --git a/REORG.TODO/sysdeps/mips/dl-procinfo.h b/REORG.TODO/sysdeps/mips/dl-procinfo.h new file mode 100644 index 0000000000..9e6d8e5a40 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/dl-procinfo.h @@ -0,0 +1,60 @@ +/* Mips version of processor capability information handling macros. + Copyright (C) 2007-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Robert Millan <rmh@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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _DL_PROCINFO_H +#define _DL_PROCINFO_H 1 + +#include <ldsodefs.h> + + +/* Mask to filter out platforms. */ +#define _DL_HWCAP_PLATFORM (-1ULL) + +#define _DL_PLATFORMS_COUNT 4 + +static inline int +__attribute__ ((unused, always_inline)) +_dl_string_platform (const char *str) +{ + int i; + + if (str != NULL) + for (i = 0; i < _DL_PLATFORMS_COUNT; ++i) + { + if (strcmp (str, GLRO(dl_mips_platforms)[i]) == 0) + return i; + } + return -1; +}; + +/* We cannot provide a general printing function. */ +#define _dl_procinfo(type, word) -1 + +/* There are no hardware capabilities defined. */ +#define _dl_hwcap_string(idx) "" + +/* By default there is no important hardware capability. */ +#define HWCAP_IMPORTANT (0) + +/* We don't have any hardware capabilities. */ +#define _DL_HWCAP_COUNT 0 + +#define _dl_string_hwcap(str) (-1) + +#endif /* dl-procinfo.h */ diff --git a/REORG.TODO/sysdeps/mips/dl-tls.h b/REORG.TODO/sysdeps/mips/dl-tls.h new file mode 100644 index 0000000000..6213333f5e --- /dev/null +++ b/REORG.TODO/sysdeps/mips/dl-tls.h @@ -0,0 +1,45 @@ +/* Thread-local storage handling in the ELF dynamic linker. MIPS version. + Copyright (C) 2005-2017 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/>. */ + + +/* Type used for the representation of TLS information in the GOT. */ +typedef struct +{ + unsigned long int ti_module; + unsigned long int ti_offset; +} tls_index; + +/* The thread pointer points 0x7000 past the first static TLS block. */ +#define TLS_TP_OFFSET 0x7000 + +/* Dynamic thread vector pointers point 0x8000 past the start of each + TLS block. */ +#define TLS_DTV_OFFSET 0x8000 + +/* Compute the value for a GOTTPREL reloc. */ +#define TLS_TPREL_VALUE(sym_map, sym) \ + ((sym_map)->l_tls_offset + (sym)->st_value - TLS_TP_OFFSET) + +/* Compute the value for a DTPREL reloc. */ +#define TLS_DTPREL_VALUE(sym) \ + ((sym)->st_value - TLS_DTV_OFFSET) + +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) diff --git a/REORG.TODO/sysdeps/mips/dl-trampoline.c b/REORG.TODO/sysdeps/mips/dl-trampoline.c new file mode 100644 index 0000000000..243c4d1f54 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/dl-trampoline.c @@ -0,0 +1,513 @@ +/* PLT trampoline. MIPS version. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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/>. */ + +/* FIXME: Profiling of shared libraries is not implemented yet. */ + +#include <sysdep.h> +#include <link.h> +#include <elf.h> +#include <ldsodefs.h> +#include <dl-machine.h> +#include <sysdep-cancel.h> + +/* Get link map for callers object containing STUB_PC. */ +static inline struct link_map * +elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc) +{ + extern int _dl_mips_gnu_objects; + + /* got[1] is reserved to keep its link map address for the shared + object generated by the gnu linker. If all are such objects, we + can find the link map from current GPREG simply. If not so, get + the link map for caller's object containing STUB_PC. */ + + if (_dl_mips_gnu_objects) + { + ElfW(Addr) *got = elf_mips_got_from_gpreg (gpreg); + ElfW(Word) g1; + + g1 = ((ElfW(Word) *) got)[1]; + + if ((g1 & ELF_MIPS_GNU_GOT1_MASK) != 0) + { + struct link_map *l = + (struct link_map *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK); + ElfW(Addr) base, limit; + const ElfW(Phdr) *p = l->l_phdr; + ElfW(Half) this, nent = l->l_phnum; + + /* For the common case of a stub being called from the containing + object, STUB_PC will point to somewhere within the object that + is described by the link map fetched via got[1]. Otherwise we + have to scan all maps. */ + for (this = 0; this < nent; this++) + { + if (p[this].p_type == PT_LOAD) + { + base = p[this].p_vaddr + l->l_addr; + limit = base + p[this].p_memsz; + if (stub_pc >= base && stub_pc < limit) + return l; + } + } + } + } + + struct link_map *l; + Lmid_t nsid; + + for (nsid = 0; nsid < DL_NNS; ++nsid) + for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next) + { + ElfW(Addr) base, limit; + const ElfW(Phdr) *p = l->l_phdr; + ElfW(Half) this, nent = l->l_phnum; + + for (this = 0; this < nent; ++this) + { + if (p[this].p_type == PT_LOAD) + { + base = p[this].p_vaddr + l->l_addr; + limit = base + p[this].p_memsz; + if (stub_pc >= base && stub_pc < limit) + return l; + } + } + } + + _dl_signal_error (0, NULL, NULL, "cannot find runtime link map"); + return NULL; +} + +/* Define mips specific runtime resolver. The function __dl_runtime_resolve + is called from assembler function _dl_runtime_resolve which converts + special argument registers t7 ($15) and t8 ($24): + t7 address to return to the caller of the function + t8 index for this function symbol in .dynsym + to usual c arguments. + + Other architectures call fixup from dl-runtime.c in + _dl_runtime_resolve. MIPS instead calls __dl_runtime_resolve. We + have to use our own version because of the way the got section is + treated on MIPS (we've also got ELF_MACHINE_PLT defined). */ + +/* The flag _dl_mips_gnu_objects is set if all dynamic objects are + generated by the gnu linker. */ +int _dl_mips_gnu_objects = 1; + +/* This is called from assembly stubs below which the compiler can't see. */ +static ElfW(Addr) +__dl_runtime_resolve (ElfW(Word), ElfW(Word), ElfW(Addr), ElfW(Addr)) + __attribute_used__; + +static ElfW(Addr) +__dl_runtime_resolve (ElfW(Word) sym_index, + ElfW(Word) return_address, + ElfW(Addr) old_gpreg, + ElfW(Addr) stub_pc) +{ + struct link_map *l = elf_machine_runtime_link_map (old_gpreg, stub_pc); + const ElfW(Sym) *const symtab + = (const ElfW(Sym) *) D_PTR (l, l_info[DT_SYMTAB]); + const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); + ElfW(Addr) *got + = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]); + const ElfW(Word) local_gotno + = (const ElfW(Word)) l->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val; + const ElfW(Word) gotsym + = (const ElfW(Word)) l->l_info[DT_MIPS (GOTSYM)]->d_un.d_val; + const ElfW(Sym) *sym = &symtab[sym_index]; + struct link_map *sym_map; + ElfW(Addr) value; + + /* FIXME: The symbol versioning stuff is not tested yet. */ + if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0) + { + switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL ? 1 : 0) + { + default: + { + const ElfW(Half) *vernum = + (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]); + ElfW(Half) ndx = vernum[sym_index] & 0x7fff; + const struct r_found_version *version = &l->l_versions[ndx]; + + if (version->hash != 0) + { + /* We need to keep the scope around so do some locking. This is + not necessary for objects which cannot be unloaded or when + we are not using any threads (yet). */ + if (!RTLD_SINGLE_THREAD_P) + THREAD_GSCOPE_SET_FLAG (); + + sym_map = _dl_lookup_symbol_x (strtab + sym->st_name, l, + &sym, l->l_scope, version, + ELF_RTYPE_CLASS_PLT, 0, 0); + + /* We are done with the global scope. */ + if (!RTLD_SINGLE_THREAD_P) + THREAD_GSCOPE_RESET_FLAG (); + + break; + } + /* Fall through. */ + } + case 0: + { + /* We need to keep the scope around so do some locking. This is + not necessary for objects which cannot be unloaded or when + we are not using any threads (yet). */ + int flags = DL_LOOKUP_ADD_DEPENDENCY; + if (!RTLD_SINGLE_THREAD_P) + { + THREAD_GSCOPE_SET_FLAG (); + flags |= DL_LOOKUP_GSCOPE_LOCK; + } + + sym_map = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, + l->l_scope, 0, ELF_RTYPE_CLASS_PLT, + flags, 0); + + /* We are done with the global scope. */ + if (!RTLD_SINGLE_THREAD_P) + THREAD_GSCOPE_RESET_FLAG (); + } + } + + /* Currently value contains the base load address of the object + that defines sym. Now add in the symbol offset. */ + value = (sym ? sym_map->l_addr + sym->st_value : 0); + } + else + /* We already found the symbol. The module (and therefore its load + address) is also known. */ + value = l->l_addr + sym->st_value; + + /* Apply the relocation with that value. */ + *(got + local_gotno + sym_index - gotsym) = value; + + return value; +} + +#if _MIPS_SIM == _ABIO32 +#define ELF_DL_FRAME_SIZE 40 + +#define ELF_DL_SAVE_ARG_REGS "\ + sw $15, 36($29)\n \ + sw $4, 16($29)\n \ + sw $5, 20($29)\n \ + sw $6, 24($29)\n \ + sw $7, 28($29)\n \ +" + +#define ELF_DL_RESTORE_ARG_REGS "\ + lw $31, 36($29)\n \ + lw $4, 16($29)\n \ + lw $5, 20($29)\n \ + lw $6, 24($29)\n \ + lw $7, 28($29)\n \ +" + +/* The PLT resolver should also save and restore $2 and $3, which are used + as arguments to MIPS16 stub functions. */ +#define ELF_DL_PLT_FRAME_SIZE 48 + +#define ELF_DL_PLT_SAVE_ARG_REGS \ + ELF_DL_SAVE_ARG_REGS "\ + sw $2, 40($29)\n \ + sw $3, 44($29)\n \ +" + +#define ELF_DL_PLT_RESTORE_ARG_REGS \ + ELF_DL_RESTORE_ARG_REGS "\ + lw $2, 40($29)\n \ + lw $3, 44($29)\n \ +" + +#define IFABIO32(X) X +#define IFNEWABI(X) + +#else /* _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 */ + +#define ELF_DL_FRAME_SIZE 80 + +#define ELF_DL_SAVE_ARG_REGS "\ + sd $15, 72($29)\n \ + sd $4, 8($29)\n \ + sd $5, 16($29)\n \ + sd $6, 24($29)\n \ + sd $7, 32($29)\n \ + sd $8, 40($29)\n \ + sd $9, 48($29)\n \ + sd $10, 56($29)\n \ + sd $11, 64($29)\n \ +" + +#define ELF_DL_RESTORE_ARG_REGS "\ + ld $31, 72($29)\n \ + ld $4, 8($29)\n \ + ld $5, 16($29)\n \ + ld $6, 24($29)\n \ + ld $7, 32($29)\n \ + ld $8, 40($29)\n \ + ld $9, 48($29)\n \ + ld $10, 56($29)\n \ + ld $11, 64($29)\n \ +" + +/* The PLT resolver should also save and restore $2 and $3, which are used + as arguments to MIPS16 stub functions. */ +#define ELF_DL_PLT_FRAME_SIZE 96 + +#define ELF_DL_PLT_SAVE_ARG_REGS \ + ELF_DL_SAVE_ARG_REGS "\ + sd $2, 80($29)\n \ + sd $3, 88($29)\n \ +" + +#define ELF_DL_PLT_RESTORE_ARG_REGS \ + ELF_DL_RESTORE_ARG_REGS "\ + ld $2, 80($29)\n \ + ld $3, 88($29)\n \ +" + +#define IFABIO32(X) +#define IFNEWABI(X) X + +#endif + +#ifndef __mips16 +asm ("\n\ + .text\n\ + .align 2\n\ + .set nomips16\n\ + .globl _dl_runtime_resolve\n\ + .type _dl_runtime_resolve,@function\n\ + .ent _dl_runtime_resolve\n\ +_dl_runtime_resolve:\n\ + .frame $29, " STRINGXP(ELF_DL_FRAME_SIZE) ", $31\n\ + .set noreorder\n\ + # Save GP.\n\ +1: move $3, $28\n\ + # Save arguments and sp value in stack.\n\ + " STRINGXP(PTR_SUBIU) " $29, " STRINGXP(ELF_DL_FRAME_SIZE) "\n\ + # Modify t9 ($25) so as to point .cpload instruction.\n\ + " IFABIO32(STRINGXP(PTR_ADDIU) " $25, (2f-1b)\n") "\ + # Compute GP.\n\ +2: " STRINGXP(SETUP_GP) "\n\ + " STRINGXV(SETUP_GP64 (0, _dl_runtime_resolve)) "\n\ + .set reorder\n\ + # Save slot call pc.\n\ + move $2, $31\n\ + " IFABIO32(STRINGXP(CPRESTORE(32))) "\n\ + " ELF_DL_SAVE_ARG_REGS "\ + move $4, $24\n\ + move $5, $15\n\ + move $6, $3\n\ + move $7, $2\n\ + jal __dl_runtime_resolve\n\ + " ELF_DL_RESTORE_ARG_REGS "\ + " STRINGXP(RESTORE_GP64) "\n\ + " STRINGXP(PTR_ADDIU) " $29, " STRINGXP(ELF_DL_FRAME_SIZE) "\n\ + move $25, $2\n\ + jr $25\n\ + .end _dl_runtime_resolve\n\ + .previous\n\ +"); + +/* Assembler veneer called from the PLT header code when using PLTs. + + Code in each PLT entry and the PLT header fills in the arguments to + this function: + + - $15 (o32 t7, n32/n64 t3) - caller's return address + - $24 (t8) - PLT entry index + - $25 (t9) - address of _dl_runtime_pltresolve + - o32 $28 (gp), n32/n64 $14 (t2) - address of .got.plt + + Different registers are used for .got.plt because the ABI was + originally designed for o32, where gp was available (call + clobbered). On n32/n64 gp is call saved. + + _dl_fixup needs: + + - $4 (a0) - link map address + - $5 (a1) - .rel.plt offset (== PLT entry index * 8) */ + +asm ("\n\ + .text\n\ + .align 2\n\ + .set nomips16\n\ + .globl _dl_runtime_pltresolve\n\ + .type _dl_runtime_pltresolve,@function\n\ + .ent _dl_runtime_pltresolve\n\ +_dl_runtime_pltresolve:\n\ + .frame $29, " STRINGXP(ELF_DL_PLT_FRAME_SIZE) ", $31\n\ + .set noreorder\n\ + # Save arguments and sp value in stack.\n\ +1: " STRINGXP(PTR_SUBIU) " $29, " STRINGXP(ELF_DL_PLT_FRAME_SIZE) "\n\ + " IFABIO32(STRINGXP(PTR_L) " $13, " STRINGXP(PTRSIZE) "($28)") "\n\ + " IFNEWABI(STRINGXP(PTR_L) " $13, " STRINGXP(PTRSIZE) "($14)") "\n\ + # Modify t9 ($25) so as to point .cpload instruction.\n\ + " IFABIO32(STRINGXP(PTR_ADDIU) " $25, (2f-1b)\n") "\ + # Compute GP.\n\ +2: " STRINGXP(SETUP_GP) "\n\ + " STRINGXV(SETUP_GP64 (0, _dl_runtime_pltresolve)) "\n\ + .set reorder\n\ + " IFABIO32(STRINGXP(CPRESTORE(32))) "\n\ + " ELF_DL_PLT_SAVE_ARG_REGS "\ + move $4, $13\n\ + sll $5, $24, " STRINGXP(PTRLOG) " + 1\n\ + jal _dl_fixup\n\ + move $25, $2\n\ + " ELF_DL_PLT_RESTORE_ARG_REGS "\ + " STRINGXP(RESTORE_GP64) "\n\ + " STRINGXP(PTR_ADDIU) " $29, " STRINGXP(ELF_DL_PLT_FRAME_SIZE) "\n\ + jr $25\n\ + .end _dl_runtime_pltresolve\n\ + .previous\n\ +"); + +#elif _MIPS_SIM == _ABIO32 /* __mips16 */ +/* MIPS16 version, O32 only. */ +asm ("\n\ + .text\n\ + .align 2\n\ + .set mips16\n\ + .globl _dl_runtime_resolve\n\ + .type _dl_runtime_resolve,@function\n\ + .ent _dl_runtime_resolve\n\ +_dl_runtime_resolve:\n\ + .frame $29, " STRINGXP (ELF_DL_FRAME_SIZE) ", $31\n\ + # Save arguments and sp value in stack.\n\t" +# if _MIPS_ISA >= _MIPS_ISA_MIPS32 + "save " STRINGXP (ELF_DL_FRAME_SIZE) ", $4-$7, $ra\n\t" +# else + "addiu $sp, -" STRINGXP (ELF_DL_FRAME_SIZE) "\n\ + sw $7, 32($sp)\n\ + sw $6, 28($sp)\n\ + sw $5, 24($sp)\n\ + sw $4, 20($sp)\n\t" +# endif + "# Preserve caller's $ra, for RESTORE instruction below.\n\ + move $5, $15\n\ + sw $5, 36($sp)\n\ + # Compute GP into $2.\n\ + li $2, %hi(_gp_disp)\n\ + addiu $3, $pc, %lo(_gp_disp)\n\ + sll $2, 16\n\ + addu $2, $3\n\ + lw $3, %got(__dl_runtime_resolve)($2)\n\ + move $4, $24\n\ + addiu $3, %lo(__dl_runtime_resolve)\n\ + move $7, $ra\n\ + move $6, $28\n\ + move $25, $3\n\ + jalr $3\n\t" +# if _MIPS_ISA >= _MIPS_ISA_MIPS32 + "restore " STRINGXP(ELF_DL_FRAME_SIZE) ", $4-$7, $ra\n\t" +# else + "# Restore $ra, move placed further down to hide latency.\n\ + lw $4, 36($sp)\n\ + lw $5, 24($sp)\n\ + lw $6, 28($sp)\n\ + lw $7, 32($sp)\n\ + move $ra, $4\n\ + lw $4, 20($sp)\n\ + addiu $sp, " STRINGXP(ELF_DL_FRAME_SIZE) "\n\t" +# endif + "move $25, $2\n\ + jr $2\n\ + .end _dl_runtime_resolve\n\ + .previous\n\ +"); + +asm ("\n\ + .text\n\ + .align 2\n\ + .set mips16\n\ + .globl _dl_runtime_pltresolve\n\ + .type _dl_runtime_pltresolve,@function\n\ + .ent _dl_runtime_pltresolve\n\ +_dl_runtime_pltresolve:\n\ + .frame $29, " STRINGXP(ELF_DL_PLT_FRAME_SIZE) ", $31\n\ + # Save arguments and sp value in stack.\n\t" +# if _MIPS_ISA >= _MIPS_ISA_MIPS32 + "save " STRINGXP(ELF_DL_PLT_FRAME_SIZE) ", $4-$7, $ra\n\t" +# else + "addiu $sp, -" STRINGXP(ELF_DL_PLT_FRAME_SIZE) "\n\ + sw $7, 40($sp)\n\ + sw $6, 36($sp)\n\ + sw $5, 32($sp)\n\ + sw $4, 28($sp)\n\t" +# endif + "# Preserve MIPS16 stub function arguments.\n\ + sw $3, 20($sp)\n\ + sw $2, 16($sp)\n\ + # Preserve caller's $ra, for RESTORE instruction below.\n\ + move $3, $15\n\ + sw $3, 44($sp)\n\ + # Compute GP into $2.\n\ + li $2, %hi(_gp_disp)\n\ + addiu $3, $pc, %lo(_gp_disp)\n\ + sll $2, 16\n\ + addu $2, $3\n\ + # Save GP value in slot.\n\ + sw $2, 24($sp)\n\ + # Load _dl_fixup address.\n\ + lw $6, %call16(_dl_fixup)($2)\n\ + # Load link map address.\n\ + move $3, $28\n\ + lw $4, " STRINGXP (PTRSIZE) "($3)\n\ + move $5, $24\n\ + sll $5, " STRINGXP (PTRLOG) " + 1\n\ + # Call _dl_fixup.\n\ + move $25, $6\n\ + jalr $6\n\ + move $25, $2\n\ + # Reload GP value into $28.\n\ + lw $3, 24($sp)\n\ + move $28, $3\n\ + lw $3, 16($sp)\n\ + move $15, $3\n\ + lw $3, 20($sp)\n\t" +# if _MIPS_ISA >= _MIPS_ISA_MIPS32 + "restore " STRINGXP (ELF_DL_PLT_FRAME_SIZE) ", $4-$7, $ra\n\t" +# else + "# Restore $ra, move placed further down to hide latency.\n\ + lw $4, 44($sp)\n\ + lw $5, 32($sp)\n\ + lw $6, 36($sp)\n\ + lw $7, 40($sp)\n\ + move $ra, $4\n\ + lw $4, 28($sp)\n\ + addiu $sp, " STRINGXP (ELF_DL_PLT_FRAME_SIZE) "\n\t" +# endif + ".set noreorder\n\ + jr $2\n\ + move $2, $15\n\ + .set reorder\n\ + .end _dl_runtime_pltresolve\n\ + .previous\n\ +"); + +#else /* __mips16 && _MIPS_SIM != _ABIO32 */ +# error "MIPS16 support for N32/N64 not implemented" + +#endif /* __mips16 */ diff --git a/REORG.TODO/sysdeps/mips/fpregdef.h b/REORG.TODO/sysdeps/mips/fpregdef.h new file mode 100644 index 0000000000..cb617ffb3b --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpregdef.h @@ -0,0 +1,23 @@ +/* Copyright (C) 1991-2017 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 _FPREGDEF_H +#define _FPREGDEF_H + +#include <sys/fpregdef.h> + +#endif /* _FPREGDEF_H */ diff --git a/REORG.TODO/sysdeps/mips/fpu/e_sqrt.c b/REORG.TODO/sysdeps/mips/fpu/e_sqrt.c new file mode 100644 index 0000000000..543cf2608b --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/e_sqrt.c @@ -0,0 +1,38 @@ +/* Copyright (C) 2002-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Hartvig Ekner <hartvige@mips.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 <sgidefs.h> + + +#if (_MIPS_ISA >= _MIPS_ISA_MIPS2) + +double __attribute__ ((nomips16)) +__ieee754_sqrt (double x) +{ + double z; + __asm__ ("sqrt.d %0,%1" : "=f" (z) : "f" (x)); + return z; +} +strong_alias (__ieee754_sqrt, __sqrt_finite) + +#else + +#include <sysdeps/ieee754/dbl-64/e_sqrt.c> + +#endif diff --git a/REORG.TODO/sysdeps/mips/fpu/e_sqrtf.c b/REORG.TODO/sysdeps/mips/fpu/e_sqrtf.c new file mode 100644 index 0000000000..f0c101185a --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/e_sqrtf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 2002-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Hartvig Ekner <hartvige@mips.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 <sgidefs.h> + + +#if (_MIPS_ISA >= _MIPS_ISA_MIPS2) + +float __attribute__ ((nomips16)) +__ieee754_sqrtf (float x) +{ + float z; + __asm__ ("sqrt.s %0,%1" : "=f" (z) : "f" (x)); + return z; +} +strong_alias (__ieee754_sqrtf, __sqrtf_finite) + +#else + +#include <sysdeps/ieee754/flt-32/e_sqrtf.c> + +#endif diff --git a/REORG.TODO/sysdeps/mips/fpu/fclrexcpt.c b/REORG.TODO/sysdeps/mips/fpu/fclrexcpt.c new file mode 100644 index 0000000000..87cb4a30d2 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fclrexcpt.c @@ -0,0 +1,47 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <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; +} +libm_hidden_def (feclearexcept) diff --git a/REORG.TODO/sysdeps/mips/fpu/fedisblxcpt.c b/REORG.TODO/sysdeps/mips/fpu/fedisblxcpt.c new file mode 100644 index 0000000000..c6d18820d3 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fedisblxcpt.c @@ -0,0 +1,40 @@ +/* Disable floating-point exceptions. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <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/REORG.TODO/sysdeps/mips/fpu/feenablxcpt.c b/REORG.TODO/sysdeps/mips/fpu/feenablxcpt.c new file mode 100644 index 0000000000..6ed90dce7b --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/feenablxcpt.c @@ -0,0 +1,40 @@ +/* Enable floating-point exceptions. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <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/REORG.TODO/sysdeps/mips/fpu/fegetenv.c b/REORG.TODO/sysdeps/mips/fpu/fegetenv.c new file mode 100644 index 0000000000..7a286add2a --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fegetenv.c @@ -0,0 +1,33 @@ +/* Store current floating-point environment. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <fenv.h> +#include <fpu_control.h> + +int +__fegetenv (fenv_t *envp) +{ + _FPU_GETCW (*envp); + + /* Success. */ + return 0; +} +libm_hidden_def (__fegetenv) +weak_alias (__fegetenv, fegetenv) +libm_hidden_weak (fegetenv) diff --git a/REORG.TODO/sysdeps/mips/fpu/fegetexcept.c b/REORG.TODO/sysdeps/mips/fpu/fegetexcept.c new file mode 100644 index 0000000000..7739f56c6d --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fegetexcept.c @@ -0,0 +1,33 @@ +/* Get enabled floating-point exceptions. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <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/REORG.TODO/sysdeps/mips/fpu/fegetmode.c b/REORG.TODO/sysdeps/mips/fpu/fegetmode.c new file mode 100644 index 0000000000..09dd978060 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fegetmode.c @@ -0,0 +1,27 @@ +/* Store current floating-point control modes. MIPS version. + Copyright (C) 2016-2017 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/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fegetmode (femode_t *modep) +{ + _FPU_GETCW (*modep); + return 0; +} diff --git a/REORG.TODO/sysdeps/mips/fpu/fegetround.c b/REORG.TODO/sysdeps/mips/fpu/fegetround.c new file mode 100644 index 0000000000..a764e473ad --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fegetround.c @@ -0,0 +1,35 @@ +/* Return current rounding direction. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <fenv.h> +#include <fpu_control.h> + +int +__fegetround (void) +{ + int cw; + + /* Get control word. */ + _FPU_GETCW (cw); + + return cw & _FPU_RC_MASK; +} +libm_hidden_def (__fegetround) +weak_alias (__fegetround, fegetround) +libm_hidden_weak (fegetround) diff --git a/REORG.TODO/sysdeps/mips/fpu/feholdexcpt.c b/REORG.TODO/sysdeps/mips/fpu/feholdexcpt.c new file mode 100644 index 0000000000..d6829e9ddb --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/feholdexcpt.c @@ -0,0 +1,41 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <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; +} + +libm_hidden_def (__feholdexcept) +weak_alias (__feholdexcept, feholdexcept) +libm_hidden_weak (feholdexcept) diff --git a/REORG.TODO/sysdeps/mips/fpu/fenv_libc.h b/REORG.TODO/sysdeps/mips/fpu/fenv_libc.h new file mode 100644 index 0000000000..fc2b82670d --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fenv_libc.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 _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/REORG.TODO/sysdeps/mips/fpu/fesetenv.c b/REORG.TODO/sysdeps/mips/fpu/fesetenv.c new file mode 100644 index 0000000000..411478273b --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fesetenv.c @@ -0,0 +1,44 @@ +/* Install given floating-point environment. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <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; +} + +libm_hidden_def (__fesetenv) +weak_alias (__fesetenv, fesetenv) +libm_hidden_weak (fesetenv) diff --git a/REORG.TODO/sysdeps/mips/fpu/fesetexcept.c b/REORG.TODO/sysdeps/mips/fpu/fesetexcept.c new file mode 100644 index 0000000000..28f61e95fd --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fesetexcept.c @@ -0,0 +1,32 @@ +/* Set given exception flags. MIPS version. + Copyright (C) 2016-2017 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/>. */ + +#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/REORG.TODO/sysdeps/mips/fpu/fesetmode.c b/REORG.TODO/sysdeps/mips/fpu/fesetmode.c new file mode 100644 index 0000000000..ed8a682682 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fesetmode.c @@ -0,0 +1,38 @@ +/* Install given floating-point control modes. MIPS version. + Copyright (C) 2016-2017 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/>. */ + +#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/REORG.TODO/sysdeps/mips/fpu/fesetround.c b/REORG.TODO/sysdeps/mips/fpu/fesetround.c new file mode 100644 index 0000000000..1631b6e3b7 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fesetround.c @@ -0,0 +1,46 @@ +/* Set current rounding direction. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <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; +} + +libm_hidden_def (__fesetround) +weak_alias (__fesetround, fesetround) +libm_hidden_weak (fesetround) diff --git a/REORG.TODO/sysdeps/mips/fpu/feupdateenv.c b/REORG.TODO/sysdeps/mips/fpu/feupdateenv.c new file mode 100644 index 0000000000..4c8e3d649b --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/feupdateenv.c @@ -0,0 +1,45 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <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 safed exception. Incidently 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; +} +libm_hidden_def (__feupdateenv) +weak_alias (__feupdateenv, feupdateenv) +libm_hidden_weak (feupdateenv) diff --git a/REORG.TODO/sysdeps/mips/fpu/fgetexcptflg.c b/REORG.TODO/sysdeps/mips/fpu/fgetexcptflg.c new file mode 100644 index 0000000000..a97cef1664 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fgetexcptflg.c @@ -0,0 +1,39 @@ +/* Store current representation for exceptions. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <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/REORG.TODO/sysdeps/mips/fpu/fraiseexcpt.c b/REORG.TODO/sysdeps/mips/fpu/fraiseexcpt.c new file mode 100644 index 0000000000..ffad16a83d --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fraiseexcpt.c @@ -0,0 +1,48 @@ +/* Raise given exceptions. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <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; +} + +libm_hidden_def (__feraiseexcept) +weak_alias (__feraiseexcept, feraiseexcept) +libm_hidden_weak (feraiseexcept) diff --git a/REORG.TODO/sysdeps/mips/fpu/fsetexcptflg.c b/REORG.TODO/sysdeps/mips/fpu/fsetexcptflg.c new file mode 100644 index 0000000000..14fa0d3bdd --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/fsetexcptflg.c @@ -0,0 +1,42 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Hartvig Ekner <hartvige@mips.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 <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/REORG.TODO/sysdeps/mips/fpu/ftestexcept.c b/REORG.TODO/sysdeps/mips/fpu/ftestexcept.c new file mode 100644 index 0000000000..548cee7d1a --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu/ftestexcept.c @@ -0,0 +1,33 @@ +/* Test exception in current environment. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <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; +} +libm_hidden_def (fetestexcept) diff --git a/REORG.TODO/sysdeps/mips/fpu_control.h b/REORG.TODO/sysdeps/mips/fpu_control.h new file mode 100644 index 0000000000..2dddf49362 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/fpu_control.h @@ -0,0 +1,133 @@ +/* FPU control word bits. Mips version. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Olaf Flebbe and Ralf Baechle. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 _FPU_CONTROL_H +#define _FPU_CONTROL_H + +/* MIPS FPU floating point control register bits. + * + * 31-25 -> floating point conditions code bits 7-1. These bits are only + * available in MIPS IV. + * 24 -> flush denormalized results to zero instead of + * causing unimplemented operation exception. This bit is only + * available for MIPS III and newer. + * 23 -> Condition bit + * 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 + * 14 -> cause bit for overflow exception + * 13 -> cause bit for underflow exception + * 12 -> cause bit for inexact exception + * 11 -> enable exception for invalid exception + * 10 -> enable exception for division by zero exception + * 9 -> enable exception for overflow exception + * 8 -> enable exception for underflow exception + * 7 -> enable exception for inexact exception + * 6 -> flag invalid exception + * 5 -> flag division by zero exception + * 4 -> flag overflow exception + * 3 -> flag underflow exception + * 2 -> flag inexact exception + * 1-0 -> rounding control + * + * + * 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) + */ + +#include <features.h> + +#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. */ +#define _FPU_FLUSH_TZ 0x1000000 + +/* 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 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 + +/* 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. */ +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 + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif /* __mips_soft_float */ + +#endif /* fpu_control.h */ diff --git a/REORG.TODO/sysdeps/mips/gccframe.h b/REORG.TODO/sysdeps/mips/gccframe.h new file mode 100644 index 0000000000..fcbfd69e75 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/gccframe.h @@ -0,0 +1,21 @@ +/* Definition of object in frame unwind info. mips version. + Copyright (C) 2001-2017 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/>. */ + +#define FIRST_PSEUDO_REGISTER 76 + +#include <sysdeps/generic/gccframe.h> diff --git a/REORG.TODO/sysdeps/mips/ieee754/ieee754.h b/REORG.TODO/sysdeps/mips/ieee754/ieee754.h new file mode 100644 index 0000000000..0e8589a87b --- /dev/null +++ b/REORG.TODO/sysdeps/mips/ieee754/ieee754.h @@ -0,0 +1,323 @@ +/* Copyright (C) 1992-2017 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 _IEEE754_H + +#define _IEEE754_H 1 +#include <features.h> + +#include <endian.h> + +#include <float.h> + +__BEGIN_DECLS + +union ieee754_float + { + float f; + + /* This is the IEEE 754 single-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:8; + unsigned int mantissa:23; +#endif /* Big endian. */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int mantissa:23; + unsigned int exponent:8; + unsigned int negative:1; +#endif /* Little endian. */ + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:8; + unsigned int quiet_nan:1; + unsigned int mantissa:22; +#endif /* Big endian. */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int mantissa:22; + unsigned int quiet_nan:1; + unsigned int exponent:8; + unsigned int negative:1; +#endif /* Little endian. */ + } ieee_nan; + }; + +#define IEEE754_FLOAT_BIAS 0x7f /* Added to exponent. */ + + +union ieee754_double + { + double d; + + /* This is the IEEE 754 double-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:11; + /* Together these comprise the mantissa. */ + unsigned int mantissa0:20; + unsigned int mantissa1:32; +#endif /* Big endian. */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +# if __FLOAT_WORD_ORDER == __BIG_ENDIAN + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; + unsigned int mantissa1:32; +# else + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; +# endif +#endif /* Little endian. */ + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:11; + unsigned int quiet_nan:1; + /* Together these comprise the mantissa. */ + unsigned int mantissa0:19; + unsigned int mantissa1:32; +#else +# if __FLOAT_WORD_ORDER == __BIG_ENDIAN + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; + unsigned int mantissa1:32; +# else + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; +# endif +#endif + } ieee_nan; + }; + +#define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */ + +#if LDBL_MANT_DIG == 113 + +union ieee854_long_double + { + long double d; + + /* This is the IEEE 854 quad-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:15; + /* Together these comprise the mantissa. */ + unsigned int mantissa0:16; + unsigned int mantissa1:32; + unsigned int mantissa2:32; + unsigned int mantissa3:32; +#endif /* Big endian. */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + /* Together these comprise the mantissa. */ + unsigned int mantissa3:32; + unsigned int mantissa2:32; + unsigned int mantissa1:32; + unsigned int mantissa0:16; + unsigned int exponent:15; + unsigned int negative:1; +#endif /* Little endian. */ + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:15; + unsigned int quiet_nan:1; + /* Together these comprise the mantissa. */ + unsigned int mantissa0:15; + unsigned int mantissa1:32; + unsigned int mantissa2:32; + unsigned int mantissa3:32; +#endif /* Big endian. */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + /* Together these comprise the mantissa. */ + unsigned int mantissa3:32; + unsigned int mantissa2:32; + unsigned int mantissa1:32; + unsigned int mantissa0:15; + unsigned int quiet_nan:1; + unsigned int exponent:15; + unsigned int negative:1; +#endif /* Little endian. */ + } ieee_nan; + }; + +#define IEEE854_LONG_DOUBLE_BIAS 0x3fff /* Added to exponent. */ + +#elif LDBL_MANT_DIG == 64 + +union ieee854_long_double + { + long double d; + + /* This is the IEEE 854 double-extended-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:15; + unsigned int empty:16; + unsigned int mantissa0:32; + unsigned int mantissa1:32; +#endif +#if __BYTE_ORDER == __LITTLE_ENDIAN +# if __FLOAT_WORD_ORDER == __BIG_ENDIAN + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; + unsigned int mantissa0:32; + unsigned int mantissa1:32; +# else + unsigned int mantissa1:32; + unsigned int mantissa0:32; + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; +# endif +#endif + } ieee; + + /* This is for NaNs in the IEEE 854 double-extended-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:15; + unsigned int empty:16; + unsigned int one:1; + unsigned int quiet_nan:1; + unsigned int mantissa0:30; + unsigned int mantissa1:32; +#endif +#if __BYTE_ORDER == __LITTLE_ENDIAN +# if __FLOAT_WORD_ORDER == __BIG_ENDIAN + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; + unsigned int mantissa0:30; + unsigned int quiet_nan:1; + unsigned int one:1; + unsigned int mantissa1:32; +# else + unsigned int mantissa1:32; + unsigned int mantissa0:30; + unsigned int quiet_nan:1; + unsigned int one:1; + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; +# endif +#endif + } ieee_nan; + }; + +#define IEEE854_LONG_DOUBLE_BIAS 0x3fff + +#elif LDBL_MANT_DIG == 53 + +union ieee854_long_double + { + long double d; + + /* This is the IEEE 754 double-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:11; + /* Together these comprise the mantissa. */ + unsigned int mantissa0:20; + unsigned int mantissa1:32; +#endif /* Big endian. */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +# if __FLOAT_WORD_ORDER == __BIG_ENDIAN + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; + unsigned int mantissa1:32; +# else + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; +# endif +#endif /* Little endian. */ + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:11; + unsigned int quiet_nan:1; + /* Together these comprise the mantissa. */ + unsigned int mantissa0:19; + unsigned int mantissa1:32; +#else +# if __FLOAT_WORD_ORDER == __BIG_ENDIAN + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; + unsigned int mantissa1:32; +# else + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; +# endif +#endif + } ieee_nan; + }; + +#define IEEE854_LONG_DOUBLE_BIAS 0x3ff /* Added to exponent. */ + +#endif /* LDBL_MANT_DIG == 53 */ + +__END_DECLS + +#endif /* ieee754.h */ diff --git a/REORG.TODO/sysdeps/mips/ieee754/s_fma.c b/REORG.TODO/sysdeps/mips/ieee754/s_fma.c new file mode 100644 index 0000000000..574141416b --- /dev/null +++ b/REORG.TODO/sysdeps/mips/ieee754/s_fma.c @@ -0,0 +1,5 @@ +#ifdef __mips_hard_float +# include <sysdeps/ieee754/dbl-64/s_fma.c> +#else +# include <soft-fp/fmadf4.c> +#endif diff --git a/REORG.TODO/sysdeps/mips/ieee754/s_fmaf.c b/REORG.TODO/sysdeps/mips/ieee754/s_fmaf.c new file mode 100644 index 0000000000..30bcdae620 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/ieee754/s_fmaf.c @@ -0,0 +1,5 @@ +#ifdef __mips_hard_float +# include <sysdeps/ieee754/dbl-64/s_fmaf.c> +#else +# include <soft-fp/fmasf4.c> +#endif diff --git a/REORG.TODO/sysdeps/mips/ieee754/s_fmal.c b/REORG.TODO/sysdeps/mips/ieee754/s_fmal.c new file mode 100644 index 0000000000..6b83e914fe --- /dev/null +++ b/REORG.TODO/sysdeps/mips/ieee754/s_fmal.c @@ -0,0 +1,7 @@ +#include <sgidefs.h> + +#if _MIPS_SIM == _ABIO32 +# error "long double fma being compiled for o32 ABI" +#endif + +#include <soft-fp/fmatf4.c> diff --git a/REORG.TODO/sysdeps/mips/include/sys/asm.h b/REORG.TODO/sysdeps/mips/include/sys/asm.h new file mode 100644 index 0000000000..b301237266 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/include/sys/asm.h @@ -0,0 +1,55 @@ +/* Copyright (C) 2013-2017 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_ASM_H +#include_next <sys/asm.h> + +# ifndef _ISOMAC + +# undef __mips_cfi_startproc +# define __mips_cfi_startproc cfi_startproc +# undef __mips_cfi_endproc +# define __mips_cfi_endproc cfi_endproc + +# if _MIPS_SIM == _ABIO32 +# define SETUP_GP64_REG_CFI(a) +# define SETUP_GP64_REG(a, b) +# define SETUP_GP64_STACK_CFI(a) +# define SETUP_GP64_STACK(a, b) +# define RESTORE_GP64_REG +# define RESTORE_GP64_STACK +# else +# define SETUP_GP64_REG_CFI(gpsavereg) \ + cfi_register (gp, gpsavereg) +# define SETUP_GP64_REG(gpsavereg, proc) \ + SETUP_GP64 (gpsavereg, proc); \ + SETUP_GP64_REG_CFI (gpsavereg) +# define SETUP_GP64_STACK_CFI(gpoffset) \ + cfi_rel_offset (gp, gpoffset) +# define SETUP_GP64_STACK(gpoffset, proc) \ + SETUP_GP64 (gpoffset, proc); \ + SETUP_GP64_STACK_CFI (gpoffset) +# define RESTORE_GP64_REG \ + RESTORE_GP64; \ + cfi_restore (gp) +# define RESTORE_GP64_STACK \ + RESTORE_GP64; \ + cfi_restore (gp) +# endif + +# endif /* _ISOMAC */ +#endif /* sys/asm.h */ diff --git a/REORG.TODO/sysdeps/mips/jmpbuf-unwind.h b/REORG.TODO/sysdeps/mips/jmpbuf-unwind.h new file mode 100644 index 0000000000..e5293ec63c --- /dev/null +++ b/REORG.TODO/sysdeps/mips/jmpbuf-unwind.h @@ -0,0 +1,47 @@ +/* Copyright (C) 2003-2017 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/>. */ + +#include <setjmp.h> +#include <stdint.h> +#include <unwind.h> +#include <sysdep.h> + +/* 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_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ + _JMPBUF_UNWINDS_ADJ (_jmpbuf, \ + (void *) (_Unwind_Ptr) _Unwind_GetCFA (_context), \ + _adj) + +static inline uintptr_t __attribute__ ((unused)) +_jmpbuf_sp (__jmp_buf regs) +{ + uintptr_t sp = (uintptr_t) regs[0].__sp; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (sp); +#endif + return sp; +} + +#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ + ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj)) + +/* We use the normal longjmp for unwinding. */ +#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val) diff --git a/REORG.TODO/sysdeps/mips/ldsodefs.h b/REORG.TODO/sysdeps/mips/ldsodefs.h new file mode 100644 index 0000000000..ba04cbbfda --- /dev/null +++ b/REORG.TODO/sysdeps/mips/ldsodefs.h @@ -0,0 +1,149 @@ +/* Run-time dynamic linker data structures for loaded ELF shared objects. + Copyright (C) 2000-2017 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 _MIPS_LDSODEFS_H +#define _MIPS_LDSODEFS_H 1 + +#include <elf.h> + +struct La_mips_32_regs; +struct La_mips_32_retval; +struct La_mips_64_regs; +struct La_mips_64_retval; + +#define ARCH_PLTENTER_MEMBERS \ + Elf32_Addr (*mips_o32_gnu_pltenter) (Elf32_Sym *, unsigned int, \ + uintptr_t *, uintptr_t *, \ + struct La_mips_32_regs *, \ + unsigned int *, const char *name, \ + long int *framesizep); \ + Elf32_Addr (*mips_n32_gnu_pltenter) (Elf32_Sym *, unsigned int, \ + uintptr_t *, uintptr_t *, \ + struct La_mips_64_regs *, \ + unsigned int *, const char *name, \ + long int *framesizep); \ + Elf64_Addr (*mips_n64_gnu_pltenter) (Elf64_Sym *, unsigned int, \ + uintptr_t *, uintptr_t *, \ + struct La_mips_64_regs *, \ + unsigned int *, const char *name, \ + long int *framesizep); + +#define ARCH_PLTEXIT_MEMBERS \ + unsigned int (*mips_o32_gnu_pltexit) (Elf32_Sym *, unsigned int, \ + uintptr_t *, uintptr_t *, \ + const struct La_mips_32_regs *, \ + struct La_mips_32_retval *, \ + const char *); \ + unsigned int (*mips_n32_gnu_pltexit) (Elf32_Sym *, unsigned int, \ + uintptr_t *, uintptr_t *, \ + const struct La_mips_64_regs *, \ + struct La_mips_64_retval *, \ + const char *); \ + unsigned int (*mips_n64_gnu_pltexit) (Elf64_Sym *, unsigned int, \ + uintptr_t *, uintptr_t *, \ + const struct La_mips_64_regs *, \ + struct La_mips_64_retval *, \ + const char *); + +/* The MIPS ABI specifies that the dynamic section has to be read-only. */ + +#define DL_RO_DYN_SECTION 1 + +#include_next <ldsodefs.h> + +/* The 64-bit MIPS ELF ABI uses an unusual reloc format. Each + relocation entry specifies up to three actual relocations, all at + the same address. The first relocation which required a symbol + uses the symbol in the r_sym field. The second relocation which + requires a symbol uses the symbol in the r_ssym field. If all + three relocations require a symbol, the third one uses a zero + value. + + We define these structures in internal headers because we're not + sure we want to make them part of the ABI yet. Eventually, some of + this may move into elf/elf.h. */ + +/* An entry in a 64 bit SHT_REL section. */ + +typedef struct +{ + Elf32_Word r_sym; /* Symbol index */ + unsigned char r_ssym; /* Special symbol for 2nd relocation */ + unsigned char r_type3; /* 3rd relocation type */ + unsigned char r_type2; /* 2nd relocation type */ + unsigned char r_type1; /* 1st relocation type */ +} _Elf64_Mips_R_Info; + +typedef union +{ + Elf64_Xword r_info_number; + _Elf64_Mips_R_Info r_info_fields; +} _Elf64_Mips_R_Info_union; + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + _Elf64_Mips_R_Info_union r_info; /* Relocation type and symbol index */ +} Elf64_Mips_Rel; + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + _Elf64_Mips_R_Info_union r_info; /* Relocation type and symbol index */ + Elf64_Sxword r_addend; /* Addend */ +} Elf64_Mips_Rela; + +#define ELF64_MIPS_R_SYM(i) \ + ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym) +#define ELF64_MIPS_R_TYPE(i) \ + (((_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1 \ + | ((Elf32_Word)(__extension__ (_Elf64_Mips_R_Info_union)(i) \ + ).r_info_fields.r_type2 << 8) \ + | ((Elf32_Word)(__extension__ (_Elf64_Mips_R_Info_union)(i) \ + ).r_info_fields.r_type3 << 16) \ + | ((Elf32_Word)(__extension__ (_Elf64_Mips_R_Info_union)(i) \ + ).r_info_fields.r_ssym << 24)) +#define ELF64_MIPS_R_INFO(sym, type) \ + (__extension__ (_Elf64_Mips_R_Info_union) \ + (__extension__ (_Elf64_Mips_R_Info) \ + { (sym), ELF64_MIPS_R_SSYM (type), \ + ELF64_MIPS_R_TYPE3 (type), \ + ELF64_MIPS_R_TYPE2 (type), \ + ELF64_MIPS_R_TYPE1 (type) \ + }).r_info_number) +/* These macros decompose the value returned by ELF64_MIPS_R_TYPE, and + compose it back into a value that it can be used as an argument to + ELF64_MIPS_R_INFO. */ +#define ELF64_MIPS_R_SSYM(i) (((i) >> 24) & 0xff) +#define ELF64_MIPS_R_TYPE3(i) (((i) >> 16) & 0xff) +#define ELF64_MIPS_R_TYPE2(i) (((i) >> 8) & 0xff) +#define ELF64_MIPS_R_TYPE1(i) ((i) & 0xff) +#define ELF64_MIPS_R_TYPEENC(type1, type2, type3, ssym) \ + ((type1) \ + | ((Elf32_Word)(type2) << 8) \ + | ((Elf32_Word)(type3) << 16) \ + | ((Elf32_Word)(ssym) << 24)) + +#undef ELF64_R_SYM +#define ELF64_R_SYM(i) ELF64_MIPS_R_SYM (i) +#undef ELF64_R_TYPE +#define ELF64_R_TYPE(i) ELF64_MIPS_R_TYPE (i) +#undef ELF64_R_INFO +#define ELF64_R_INFO(sym, type) ELF64_MIPS_R_INFO ((sym), (type)) + +#endif diff --git a/REORG.TODO/sysdeps/mips/libc-tls.c b/REORG.TODO/sysdeps/mips/libc-tls.c new file mode 100644 index 0000000000..864e89b35d --- /dev/null +++ b/REORG.TODO/sysdeps/mips/libc-tls.c @@ -0,0 +1,32 @@ +/* Thread-local storage handling in the ELF dynamic linker. MIPS version. + Copyright (C) 2005-2017 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/>. */ + +#include <csu/libc-tls.c> +#include <dl-tls.h> + +/* On MIPS, linker optimizations are not required, so __tls_get_addr + can be called even in statically linked binaries. In this case module + must be always 1 and PT_TLS segment exist in the binary, otherwise it + would not link. */ + +void * +__tls_get_addr (tls_index *ti) +{ + dtv_t *dtv = THREAD_DTV (); + return (char *) dtv[1].pointer.val + GET_ADDR_OFFSET; +} diff --git a/REORG.TODO/sysdeps/mips/linkmap.h b/REORG.TODO/sysdeps/mips/linkmap.h new file mode 100644 index 0000000000..1fb9678a6d --- /dev/null +++ b/REORG.TODO/sysdeps/mips/linkmap.h @@ -0,0 +1,6 @@ +struct link_map_machine + { + ElfW(Addr) plt; /* Address of .plt */ + ElfW(Word) fpabi; /* FP ABI of the object */ + unsigned int odd_spreg; /* Does the object require odd_spreg support? */ + }; diff --git a/REORG.TODO/sysdeps/mips/localplt.data b/REORG.TODO/sysdeps/mips/localplt.data new file mode 100644 index 0000000000..f0c5970c08 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/localplt.data @@ -0,0 +1,3 @@ +# MIPS does not use PLTs in shared libraries, and implicit GOT +# relocation means this test cannot check for GOT relocations as an +# alternative. diff --git a/REORG.TODO/sysdeps/mips/lshift.S b/REORG.TODO/sysdeps/mips/lshift.S new file mode 100644 index 0000000000..46117aa89e --- /dev/null +++ b/REORG.TODO/sysdeps/mips/lshift.S @@ -0,0 +1,97 @@ +/* MIPS2 __mpn_lshift -- + +Copyright (C) 1995-2017 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library. If not, see +<http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +/* INPUT PARAMETERS + res_ptr $4 + src_ptr $5 + size $6 + cnt $7 +*/ +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__mpn_lshift) + .set noreorder +#ifdef __PIC__ + .cpload t9 +#endif + .set nomacro + + sll $2,$6,2 + addu $5,$5,$2 /* make r5 point at end of src */ + lw $10,-4($5) /* load first limb */ + subu $13,$0,$7 + addu $4,$4,$2 /* make r4 point at end of res */ + addiu $6,$6,-1 + and $9,$6,4-1 /* number of limbs in first loop */ + beq $9,$0,L(L0) /* if multiple of 4 limbs, skip first loop */ + srl $2,$10,$13 /* compute function result */ + + subu $6,$6,$9 + +L(Loop0): lw $3,-8($5) + addiu $4,$4,-4 + addiu $5,$5,-4 + addiu $9,$9,-1 + sll $11,$10,$7 + srl $12,$3,$13 + move $10,$3 + or $8,$11,$12 + bne $9,$0,L(Loop0) + sw $8,0($4) + +L(L0): beq $6,$0,L(Lend) + nop + +L(Loop): lw $3,-8($5) + addiu $4,$4,-16 + addiu $6,$6,-4 + sll $11,$10,$7 + srl $12,$3,$13 + + lw $10,-12($5) + sll $14,$3,$7 + or $8,$11,$12 + sw $8,12($4) + srl $9,$10,$13 + + lw $3,-16($5) + sll $11,$10,$7 + or $8,$14,$9 + sw $8,8($4) + srl $12,$3,$13 + + lw $10,-20($5) + sll $14,$3,$7 + or $8,$11,$12 + sw $8,4($4) + srl $9,$10,$13 + + addiu $5,$5,-16 + or $8,$14,$9 + bgtz $6,L(Loop) + sw $8,0($4) + +L(Lend): sll $8,$10,$7 + j $31 + sw $8,-4($4) + END (__mpn_lshift) diff --git a/REORG.TODO/sysdeps/mips/machine-gmon.h b/REORG.TODO/sysdeps/mips/machine-gmon.h new file mode 100644 index 0000000000..e99d13e4a6 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/machine-gmon.h @@ -0,0 +1,146 @@ +/* Machine-specific calling sequence for `mcount' profiling function. MIPS + Copyright (C) 1996-2017 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/>. */ + +#include <sgidefs.h> + +#define _MCOUNT_DECL(frompc,selfpc) \ +static void __attribute_used__ __mcount (u_long frompc, u_long selfpc) + +/* Call __mcount with the return PC for our caller, + and the return PC our caller will return to. */ + +#if _MIPS_SIM == _ABIO32 + +#ifdef __PIC__ +# define CPLOAD ".cpload $25;" +# define CPRESTORE ".cprestore 44\n\t" +#else +# define CPLOAD +# define CPRESTORE +#endif + +#define MCOUNT asm(\ + ".globl _mcount;\n\t" \ + ".align 2;\n\t" \ + ".set push;\n\t" \ + ".set nomips16;\n\t" \ + ".type _mcount,@function;\n\t" \ + ".ent _mcount\n\t" \ + "_mcount:\n\t" \ + ".frame $sp,44,$31\n\t" \ + ".set noreorder;\n\t" \ + ".set noat;\n\t" \ + CPLOAD \ + "subu $29,$29,48;\n\t" \ + CPRESTORE \ + "sw $4,24($29);\n\t" \ + "sw $5,28($29);\n\t" \ + "sw $6,32($29);\n\t" \ + "sw $7,36($29);\n\t" \ + "sw $2,40($29);\n\t" \ + "sw $1,16($29);\n\t" \ + "sw $31,20($29);\n\t" \ + "move $5,$31;\n\t" \ + "move $4,$1;\n\t" \ + "jal __mcount;\n\t" \ + "nop;\n\t" \ + "lw $4,24($29);\n\t" \ + "lw $5,28($29);\n\t" \ + "lw $6,32($29);\n\t" \ + "lw $7,36($29);\n\t" \ + "lw $2,40($29);\n\t" \ + "lw $31,20($29);\n\t" \ + "lw $1,16($29);\n\t" \ + "addu $29,$29,56;\n\t" \ + "j $31;\n\t" \ + "move $31,$1;\n\t" \ + ".end _mcount;\n\t" \ + ".set pop"); + +#else + +#ifdef __PIC__ +# define CPSETUP ".cpsetup $25, 88, _mcount;" +# define CPRETURN ".cpreturn;" +#else +# define CPSETUP +# define CPRETURN +#endif + +#if _MIPS_SIM == _ABIN32 +# if !defined __mips_isa_rev || __mips_isa_rev < 6 +# define PTR_ADDU_STRING "add" /* no u */ +# define PTR_SUBU_STRING "sub" /* no u */ +# else +# define PTR_ADDU_STRING "addu" +# define PTR_SUBU_STRING "subu" +# endif +#elif _MIPS_SIM == _ABI64 +# define PTR_ADDU_STRING "daddu" +# define PTR_SUBU_STRING "dsubu" +#else +# error "Unknown ABI" +#endif + +#define MCOUNT asm(\ + ".globl _mcount;\n\t" \ + ".align 3;\n\t" \ + ".set push;\n\t" \ + ".set nomips16;\n\t" \ + ".type _mcount,@function;\n\t" \ + ".ent _mcount\n\t" \ + "_mcount:\n\t" \ + ".frame $sp,88,$31\n\t" \ + ".set noreorder;\n\t" \ + ".set noat;\n\t" \ + PTR_SUBU_STRING " $29,$29,96;\n\t" \ + CPSETUP \ + "sd $4,24($29);\n\t" \ + "sd $5,32($29);\n\t" \ + "sd $6,40($29);\n\t" \ + "sd $7,48($29);\n\t" \ + "sd $8,56($29);\n\t" \ + "sd $9,64($29);\n\t" \ + "sd $10,72($29);\n\t" \ + "sd $11,80($29);\n\t" \ + "sd $2,16($29);\n\t" \ + "sd $1,0($29);\n\t" \ + "sd $31,8($29);\n\t" \ + "move $5,$31;\n\t" \ + "move $4,$1;\n\t" \ + "jal __mcount;\n\t" \ + "nop;\n\t" \ + "ld $4,24($29);\n\t" \ + "ld $5,32($29);\n\t" \ + "ld $6,40($29);\n\t" \ + "ld $7,48($29);\n\t" \ + "ld $8,56($29);\n\t" \ + "ld $9,64($29);\n\t" \ + "ld $10,72($29);\n\t" \ + "ld $11,80($29);\n\t" \ + "ld $2,16($29);\n\t" \ + "ld $31,8($29);\n\t" \ + "ld $1,0($29);\n\t" \ + CPRETURN \ + PTR_ADDU_STRING " $29,$29,96;\n\t" \ + "j $31;\n\t" \ + "move $31,$1;\n\t" \ + ".end _mcount;\n\t" \ + ".set pop"); + +#endif diff --git a/REORG.TODO/sysdeps/mips/math-tests.h b/REORG.TODO/sysdeps/mips/math-tests.h new file mode 100644 index 0000000000..7680db21ee --- /dev/null +++ b/REORG.TODO/sysdeps/mips/math-tests.h @@ -0,0 +1,44 @@ +/* Configuration for math tests. MIPS version. + Copyright (C) 2013-2017 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/>. */ + +#include <features.h> +#include <sgidefs.h> + +/* MIPS soft float does not support exceptions and rounding modes, and + before GCC 4.9 long double when wider than double is implemented + using fp-bit which does not integrate with hardware exceptions and + rounding modes. */ +#ifdef __mips_soft_float +# define ROUNDING_TESTS_float(MODE) ((MODE) == FE_TONEAREST) +# define ROUNDING_TESTS_double(MODE) ((MODE) == FE_TONEAREST) +# define ROUNDING_TESTS_long_double(MODE) ((MODE) == FE_TONEAREST) +# define EXCEPTION_TESTS_float 0 +# define EXCEPTION_TESTS_double 0 +# define EXCEPTION_TESTS_long_double 0 +#elif _MIPS_SIM != _ABIO32 && !__GNUC_PREREQ (4, 9) +# define ROUNDING_TESTS_long_double(MODE) ((MODE) == FE_TONEAREST) +# define EXCEPTION_TESTS_long_double 0 +#endif + +/* NaN payload preservation when converting a signaling NaN to quiet + is only required in NAN2008 mode. */ +#ifndef __mips_nan2008 +# define SNAN_TESTS_PRESERVE_PAYLOAD 0 +#endif + +#include_next <math-tests.h> diff --git a/REORG.TODO/sysdeps/mips/math_private.h b/REORG.TODO/sysdeps/mips/math_private.h new file mode 100644 index 0000000000..05f1f084a4 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/math_private.h @@ -0,0 +1,249 @@ +/* Internal math stuff. MIPS version. + Copyright (C) 2013-2017 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 MIPS_MATH_PRIVATE_H +#define MIPS_MATH_PRIVATE_H 1 + +/* Inline functions to speed up the math library implementation. The + default versions of these routines are in generic/math_private.h + and call fesetround, feholdexcept, etc. These routines use inlined + code instead. */ + +#ifdef __mips_hard_float + +# 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 + +/* Enable __finitel, __isinfl, and __isnanl for binary compatibility + when built without long double support. */ +#define LDBL_CLASSIFY_COMPAT 1 + +#include_next <math_private.h> + +#endif diff --git a/REORG.TODO/sysdeps/mips/memcpy.S b/REORG.TODO/sysdeps/mips/memcpy.S new file mode 100644 index 0000000000..af01d0dd73 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/memcpy.S @@ -0,0 +1,868 @@ +/* Copyright (C) 2012-2017 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/>. */ + +#ifdef ANDROID_CHANGES +# include "machine/asm.h" +# include "machine/regdef.h" +# define USE_MEMMOVE_FOR_OVERLAP +# define PREFETCH_LOAD_HINT PREFETCH_HINT_LOAD_STREAMED +# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE +#elif _LIBC +# include <sysdep.h> +# include <regdef.h> +# include <sys/asm.h> +# define PREFETCH_LOAD_HINT PREFETCH_HINT_LOAD_STREAMED +# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE +#elif defined _COMPILING_NEWLIB +# include "machine/asm.h" +# include "machine/regdef.h" +# define PREFETCH_LOAD_HINT PREFETCH_HINT_LOAD_STREAMED +# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE +#else +# include <regdef.h> +# include <sys/asm.h> +#endif + +#if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) +# ifndef DISABLE_PREFETCH +# define USE_PREFETCH +# endif +#endif + +#if defined(_MIPS_SIM) && ((_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32)) +# ifndef DISABLE_DOUBLE +# define USE_DOUBLE +# endif +#endif + +/* Some asm.h files do not have the L macro definition. */ +#ifndef L +# if _MIPS_SIM == _ABIO32 +# define L(label) $L ## label +# else +# define L(label) .L ## label +# endif +#endif + +/* Some asm.h files do not have the PTR_ADDIU macro definition. */ +#ifndef PTR_ADDIU +# ifdef USE_DOUBLE +# define PTR_ADDIU daddiu +# else +# define PTR_ADDIU addiu +# endif +#endif + +/* Some asm.h files do not have the PTR_SRA macro definition. */ +#ifndef PTR_SRA +# ifdef USE_DOUBLE +# define PTR_SRA dsra +# else +# define PTR_SRA sra +# endif +#endif + +/* New R6 instructions that may not be in asm.h. */ +#ifndef PTR_LSA +# if _MIPS_SIM == _ABI64 +# define PTR_LSA dlsa +# else +# define PTR_LSA lsa +# endif +#endif + +/* + * Using PREFETCH_HINT_LOAD_STREAMED instead of PREFETCH_LOAD on load + * prefetches appears to offer a slight preformance advantage. + * + * Using PREFETCH_HINT_PREPAREFORSTORE instead of PREFETCH_STORE + * or PREFETCH_STORE_STREAMED offers a large performance advantage + * but PREPAREFORSTORE has some special restrictions to consider. + * + * Prefetch with the 'prepare for store' hint does not copy a memory + * location into the cache, it just allocates a cache line and zeros + * it out. This means that if you do not write to the entire cache + * line before writing it out to memory some data will get zero'ed out + * when the cache line is written back to memory and data will be lost. + * + * Also if you are using this memcpy to copy overlapping buffers it may + * not behave correctly when using the 'prepare for store' hint. If you + * use the 'prepare for store' prefetch on a memory area that is in the + * memcpy source (as well as the memcpy destination), then you will get + * some data zero'ed out before you have a chance to read it and data will + * be lost. + * + * If you are going to use this memcpy routine with the 'prepare for store' + * prefetch you may want to set USE_MEMMOVE_FOR_OVERLAP in order to avoid + * the problem of running memcpy on overlapping buffers. + * + * There are ifdef'ed sections of this memcpy to make sure that it does not + * do prefetches on cache lines that are not going to be completely written. + * This code is only needed and only used when PREFETCH_STORE_HINT is set to + * PREFETCH_HINT_PREPAREFORSTORE. This code assumes that cache lines are + * 32 bytes and if the cache line is larger it will not work correctly. + */ + +#ifdef USE_PREFETCH +# define PREFETCH_HINT_LOAD 0 +# define PREFETCH_HINT_STORE 1 +# define PREFETCH_HINT_LOAD_STREAMED 4 +# define PREFETCH_HINT_STORE_STREAMED 5 +# define PREFETCH_HINT_LOAD_RETAINED 6 +# define PREFETCH_HINT_STORE_RETAINED 7 +# define PREFETCH_HINT_WRITEBACK_INVAL 25 +# define PREFETCH_HINT_PREPAREFORSTORE 30 + +/* + * If we have not picked out what hints to use at this point use the + * standard load and store prefetch hints. + */ +# ifndef PREFETCH_STORE_HINT +# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE +# endif +# ifndef PREFETCH_LOAD_HINT +# define PREFETCH_LOAD_HINT PREFETCH_HINT_LOAD +# endif + +/* + * We double everything when USE_DOUBLE is true so we do 2 prefetches to + * get 64 bytes in that case. The assumption is that each individual + * prefetch brings in 32 bytes. + */ + +# ifdef USE_DOUBLE +# define PREFETCH_CHUNK 64 +# define PREFETCH_FOR_LOAD(chunk, reg) \ + pref PREFETCH_LOAD_HINT, (chunk)*64(reg); \ + pref PREFETCH_LOAD_HINT, ((chunk)*64)+32(reg) +# define PREFETCH_FOR_STORE(chunk, reg) \ + pref PREFETCH_STORE_HINT, (chunk)*64(reg); \ + pref PREFETCH_STORE_HINT, ((chunk)*64)+32(reg) +# else +# define PREFETCH_CHUNK 32 +# define PREFETCH_FOR_LOAD(chunk, reg) \ + pref PREFETCH_LOAD_HINT, (chunk)*32(reg) +# define PREFETCH_FOR_STORE(chunk, reg) \ + pref PREFETCH_STORE_HINT, (chunk)*32(reg) +# endif +/* MAX_PREFETCH_SIZE is the maximum size of a prefetch, it must not be less + * than PREFETCH_CHUNK, the assumed size of each prefetch. If the real size + * of a prefetch is greater than MAX_PREFETCH_SIZE and the PREPAREFORSTORE + * hint is used, the code will not work correctly. If PREPAREFORSTORE is not + * used then MAX_PREFETCH_SIZE does not matter. */ +# define MAX_PREFETCH_SIZE 128 +/* PREFETCH_LIMIT is set based on the fact that we never use an offset greater + * than 5 on a STORE prefetch and that a single prefetch can never be larger + * than MAX_PREFETCH_SIZE. We add the extra 32 when USE_DOUBLE is set because + * we actually do two prefetches in that case, one 32 bytes after the other. */ +# ifdef USE_DOUBLE +# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + 32 + MAX_PREFETCH_SIZE +# else +# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + MAX_PREFETCH_SIZE +# endif +# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) \ + && ((PREFETCH_CHUNK * 4) < MAX_PREFETCH_SIZE) +/* We cannot handle this because the initial prefetches may fetch bytes that + * are before the buffer being copied. We start copies with an offset + * of 4 so avoid this situation when using PREPAREFORSTORE. */ +#error "PREFETCH_CHUNK is too large and/or MAX_PREFETCH_SIZE is too small." +# endif +#else /* USE_PREFETCH not defined */ +# define PREFETCH_FOR_LOAD(offset, reg) +# define PREFETCH_FOR_STORE(offset, reg) +#endif + +#if __mips_isa_rev > 5 +# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) +# undef PREFETCH_STORE_HINT +# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE_STREAMED +# endif +# define R6_CODE +#endif + +/* Allow the routine to be named something else if desired. */ +#ifndef MEMCPY_NAME +# define MEMCPY_NAME memcpy +#endif + +/* We use these 32/64 bit registers as temporaries to do the copying. */ +#define REG0 t0 +#define REG1 t1 +#define REG2 t2 +#define REG3 t3 +#if defined(_MIPS_SIM) && ((_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABIO64)) +# define REG4 t4 +# define REG5 t5 +# define REG6 t6 +# define REG7 t7 +#else +# define REG4 ta0 +# define REG5 ta1 +# define REG6 ta2 +# define REG7 ta3 +#endif + +/* We load/store 64 bits at a time when USE_DOUBLE is true. + * The C_ prefix stands for CHUNK and is used to avoid macro name + * conflicts with system header files. */ + +#ifdef USE_DOUBLE +# define C_ST sd +# define C_LD ld +# ifdef __MIPSEB +# define C_LDHI ldl /* high part is left in big-endian */ +# define C_STHI sdl /* high part is left in big-endian */ +# define C_LDLO ldr /* low part is right in big-endian */ +# define C_STLO sdr /* low part is right in big-endian */ +# else +# define C_LDHI ldr /* high part is right in little-endian */ +# define C_STHI sdr /* high part is right in little-endian */ +# define C_LDLO ldl /* low part is left in little-endian */ +# define C_STLO sdl /* low part is left in little-endian */ +# endif +# define C_ALIGN dalign /* r6 align instruction */ +#else +# define C_ST sw +# define C_LD lw +# ifdef __MIPSEB +# define C_LDHI lwl /* high part is left in big-endian */ +# define C_STHI swl /* high part is left in big-endian */ +# define C_LDLO lwr /* low part is right in big-endian */ +# define C_STLO swr /* low part is right in big-endian */ +# else +# define C_LDHI lwr /* high part is right in little-endian */ +# define C_STHI swr /* high part is right in little-endian */ +# define C_LDLO lwl /* low part is left in little-endian */ +# define C_STLO swl /* low part is left in little-endian */ +# endif +# define C_ALIGN align /* r6 align instruction */ +#endif + +/* Bookkeeping values for 32 vs. 64 bit mode. */ +#ifdef USE_DOUBLE +# define NSIZE 8 +# define NSIZEMASK 0x3f +# define NSIZEDMASK 0x7f +#else +# define NSIZE 4 +# define NSIZEMASK 0x1f +# define NSIZEDMASK 0x3f +#endif +#define UNIT(unit) ((unit)*NSIZE) +#define UNITM1(unit) (((unit)*NSIZE)-1) + +#ifdef ANDROID_CHANGES +LEAF(MEMCPY_NAME, 0) +#else +LEAF(MEMCPY_NAME) +#endif + .set nomips16 + .set noreorder +/* + * Below we handle the case where memcpy is called with overlapping src and dst. + * Although memcpy is not required to handle this case, some parts of Android + * like Skia rely on such usage. We call memmove to handle such cases. + */ +#ifdef USE_MEMMOVE_FOR_OVERLAP + PTR_SUBU t0,a0,a1 + PTR_SRA t2,t0,31 + xor t1,t0,t2 + PTR_SUBU t0,t1,t2 + sltu t2,t0,a2 + beq t2,zero,L(memcpy) + la t9,memmove + jr t9 + nop +L(memcpy): +#endif +/* + * If the size is less than 2*NSIZE (8 or 16), go to L(lastb). Regardless of + * size, copy dst pointer to v0 for the return value. + */ + slti t2,a2,(2 * NSIZE) + bne t2,zero,L(lasts) +#if defined(RETURN_FIRST_PREFETCH) || defined(RETURN_LAST_PREFETCH) + move v0,zero +#else + move v0,a0 +#endif + +#ifndef R6_CODE + +/* + * If src and dst have different alignments, go to L(unaligned), if they + * have the same alignment (but are not actually aligned) do a partial + * load/store to make them aligned. If they are both already aligned + * we can start copying at L(aligned). + */ + xor t8,a1,a0 + andi t8,t8,(NSIZE-1) /* t8 is a0/a1 word-displacement */ + bne t8,zero,L(unaligned) + PTR_SUBU a3, zero, a0 + + andi a3,a3,(NSIZE-1) /* copy a3 bytes to align a0/a1 */ + beq a3,zero,L(aligned) /* if a3=0, it is already aligned */ + PTR_SUBU a2,a2,a3 /* a2 is the remining bytes count */ + + C_LDHI t8,0(a1) + PTR_ADDU a1,a1,a3 + C_STHI t8,0(a0) + PTR_ADDU a0,a0,a3 + +#else /* R6_CODE */ + +/* + * Align the destination and hope that the source gets aligned too. If it + * doesn't we jump to L(r6_unaligned*) to do unaligned copies using the r6 + * align instruction. + */ + andi t8,a0,7 + lapc t9,L(atable) + PTR_LSA t9,t8,t9,2 + jrc t9 +L(atable): + bc L(lb0) + bc L(lb7) + bc L(lb6) + bc L(lb5) + bc L(lb4) + bc L(lb3) + bc L(lb2) + bc L(lb1) +L(lb7): + lb a3, 6(a1) + sb a3, 6(a0) +L(lb6): + lb a3, 5(a1) + sb a3, 5(a0) +L(lb5): + lb a3, 4(a1) + sb a3, 4(a0) +L(lb4): + lb a3, 3(a1) + sb a3, 3(a0) +L(lb3): + lb a3, 2(a1) + sb a3, 2(a0) +L(lb2): + lb a3, 1(a1) + sb a3, 1(a0) +L(lb1): + lb a3, 0(a1) + sb a3, 0(a0) + + li t9,8 + subu t8,t9,t8 + PTR_SUBU a2,a2,t8 + PTR_ADDU a0,a0,t8 + PTR_ADDU a1,a1,t8 +L(lb0): + + andi t8,a1,(NSIZE-1) + lapc t9,L(jtable) + PTR_LSA t9,t8,t9,2 + jrc t9 +L(jtable): + bc L(aligned) + bc L(r6_unaligned1) + bc L(r6_unaligned2) + bc L(r6_unaligned3) +# ifdef USE_DOUBLE + bc L(r6_unaligned4) + bc L(r6_unaligned5) + bc L(r6_unaligned6) + bc L(r6_unaligned7) +# endif +#endif /* R6_CODE */ + +L(aligned): + +/* + * Now dst/src are both aligned to (word or double word) aligned addresses + * Set a2 to count how many bytes we have to copy after all the 64/128 byte + * chunks are copied and a3 to the dst pointer after all the 64/128 byte + * chunks have been copied. We will loop, incrementing a0 and a1 until a0 + * equals a3. + */ + + andi t8,a2,NSIZEDMASK /* any whole 64-byte/128-byte chunks? */ + beq a2,t8,L(chkw) /* if a2==t8, no 64-byte/128-byte chunks */ + PTR_SUBU a3,a2,t8 /* subtract from a2 the reminder */ + PTR_ADDU a3,a0,a3 /* Now a3 is the final dst after loop */ + +/* When in the loop we may prefetch with the 'prepare to store' hint, + * in this case the a0+x should not be past the "t0-32" address. This + * means: for x=128 the last "safe" a0 address is "t0-160". Alternatively, + * for x=64 the last "safe" a0 address is "t0-96" In the current version we + * will use "prefetch hint,128(a0)", so "t0-160" is the limit. + */ +#if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) + PTR_ADDU t0,a0,a2 /* t0 is the "past the end" address */ + PTR_SUBU t9,t0,PREFETCH_LIMIT /* t9 is the "last safe pref" address */ +#endif + PREFETCH_FOR_LOAD (0, a1) + PREFETCH_FOR_LOAD (1, a1) + PREFETCH_FOR_LOAD (2, a1) + PREFETCH_FOR_LOAD (3, a1) +#if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE) + PREFETCH_FOR_STORE (1, a0) + PREFETCH_FOR_STORE (2, a0) + PREFETCH_FOR_STORE (3, a0) +#endif +#if defined(RETURN_FIRST_PREFETCH) && defined(USE_PREFETCH) +# if PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE + sltu v1,t9,a0 + bgtz v1,L(skip_set) + nop + PTR_ADDIU v0,a0,(PREFETCH_CHUNK*4) +L(skip_set): +# else + PTR_ADDIU v0,a0,(PREFETCH_CHUNK*1) +# endif +#endif +#if defined(RETURN_LAST_PREFETCH) && defined(USE_PREFETCH) \ + && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE) + PTR_ADDIU v0,a0,(PREFETCH_CHUNK*3) +# ifdef USE_DOUBLE + PTR_ADDIU v0,v0,32 +# endif +#endif +L(loop16w): + C_LD t0,UNIT(0)(a1) +#if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) + sltu v1,t9,a0 /* If a0 > t9 don't use next prefetch */ + bgtz v1,L(skip_pref) +#endif + C_LD t1,UNIT(1)(a1) +#ifdef R6_CODE + PREFETCH_FOR_STORE (2, a0) +#else + PREFETCH_FOR_STORE (4, a0) + PREFETCH_FOR_STORE (5, a0) +#endif +#if defined(RETURN_LAST_PREFETCH) && defined(USE_PREFETCH) + PTR_ADDIU v0,a0,(PREFETCH_CHUNK*5) +# ifdef USE_DOUBLE + PTR_ADDIU v0,v0,32 +# endif +#endif +L(skip_pref): + C_LD REG2,UNIT(2)(a1) + C_LD REG3,UNIT(3)(a1) + C_LD REG4,UNIT(4)(a1) + C_LD REG5,UNIT(5)(a1) + C_LD REG6,UNIT(6)(a1) + C_LD REG7,UNIT(7)(a1) +#ifdef R6_CODE + PREFETCH_FOR_LOAD (3, a1) +#else + PREFETCH_FOR_LOAD (4, a1) +#endif + C_ST t0,UNIT(0)(a0) + C_ST t1,UNIT(1)(a0) + C_ST REG2,UNIT(2)(a0) + C_ST REG3,UNIT(3)(a0) + C_ST REG4,UNIT(4)(a0) + C_ST REG5,UNIT(5)(a0) + C_ST REG6,UNIT(6)(a0) + C_ST REG7,UNIT(7)(a0) + + C_LD t0,UNIT(8)(a1) + C_LD t1,UNIT(9)(a1) + C_LD REG2,UNIT(10)(a1) + C_LD REG3,UNIT(11)(a1) + C_LD REG4,UNIT(12)(a1) + C_LD REG5,UNIT(13)(a1) + C_LD REG6,UNIT(14)(a1) + C_LD REG7,UNIT(15)(a1) +#ifndef R6_CODE + PREFETCH_FOR_LOAD (5, a1) +#endif + C_ST t0,UNIT(8)(a0) + C_ST t1,UNIT(9)(a0) + C_ST REG2,UNIT(10)(a0) + C_ST REG3,UNIT(11)(a0) + C_ST REG4,UNIT(12)(a0) + C_ST REG5,UNIT(13)(a0) + C_ST REG6,UNIT(14)(a0) + C_ST REG7,UNIT(15)(a0) + PTR_ADDIU a0,a0,UNIT(16) /* adding 64/128 to dest */ + bne a0,a3,L(loop16w) + PTR_ADDIU a1,a1,UNIT(16) /* adding 64/128 to src */ + move a2,t8 + +/* Here we have src and dest word-aligned but less than 64-bytes or + * 128 bytes to go. Check for a 32(64) byte chunk and copy if if there + * is one. Otherwise jump down to L(chk1w) to handle the tail end of + * the copy. + */ + +L(chkw): + PREFETCH_FOR_LOAD (0, a1) + andi t8,a2,NSIZEMASK /* Is there a 32-byte/64-byte chunk. */ + /* The t8 is the reminder count past 32-bytes */ + beq a2,t8,L(chk1w) /* When a2=t8, no 32-byte chunk */ + nop + C_LD t0,UNIT(0)(a1) + C_LD t1,UNIT(1)(a1) + C_LD REG2,UNIT(2)(a1) + C_LD REG3,UNIT(3)(a1) + C_LD REG4,UNIT(4)(a1) + C_LD REG5,UNIT(5)(a1) + C_LD REG6,UNIT(6)(a1) + C_LD REG7,UNIT(7)(a1) + PTR_ADDIU a1,a1,UNIT(8) + C_ST t0,UNIT(0)(a0) + C_ST t1,UNIT(1)(a0) + C_ST REG2,UNIT(2)(a0) + C_ST REG3,UNIT(3)(a0) + C_ST REG4,UNIT(4)(a0) + C_ST REG5,UNIT(5)(a0) + C_ST REG6,UNIT(6)(a0) + C_ST REG7,UNIT(7)(a0) + PTR_ADDIU a0,a0,UNIT(8) + +/* + * Here we have less than 32(64) bytes to copy. Set up for a loop to + * copy one word (or double word) at a time. Set a2 to count how many + * bytes we have to copy after all the word (or double word) chunks are + * copied and a3 to the dst pointer after all the (d)word chunks have + * been copied. We will loop, incrementing a0 and a1 until a0 equals a3. + */ +L(chk1w): + andi a2,t8,(NSIZE-1) /* a2 is the reminder past one (d)word chunks */ + beq a2,t8,L(lastw) + PTR_SUBU a3,t8,a2 /* a3 is count of bytes in one (d)word chunks */ + PTR_ADDU a3,a0,a3 /* a3 is the dst address after loop */ + +/* copying in words (4-byte or 8-byte chunks) */ +L(wordCopy_loop): + C_LD REG3,UNIT(0)(a1) + PTR_ADDIU a0,a0,UNIT(1) + PTR_ADDIU a1,a1,UNIT(1) + bne a0,a3,L(wordCopy_loop) + C_ST REG3,UNIT(-1)(a0) + +/* If we have been copying double words, see if we can copy a single word + before doing byte copies. We can have, at most, one word to copy. */ + +L(lastw): +#ifdef USE_DOUBLE + andi t8,a2,3 /* a2 is the remainder past 4 byte chunks. */ + beq t8,a2,L(lastb) + move a2,t8 + lw REG3,0(a1) + sw REG3,0(a0) + PTR_ADDIU a0,a0,4 + PTR_ADDIU a1,a1,4 +#endif + +/* Copy the last 8 (or 16) bytes */ +L(lastb): + blez a2,L(leave) + PTR_ADDU a3,a0,a2 /* a3 is the last dst address */ +L(lastbloop): + lb v1,0(a1) + PTR_ADDIU a0,a0,1 + PTR_ADDIU a1,a1,1 + bne a0,a3,L(lastbloop) + sb v1,-1(a0) +L(leave): + j ra + nop + +/* We jump here with a memcpy of less than 8 or 16 bytes, depending on + whether or not USE_DOUBLE is defined. Instead of just doing byte + copies, check the alignment and size and use lw/sw if possible. + Otherwise, do byte copies. */ + +L(lasts): + andi t8,a2,3 + beq t8,a2,L(lastb) + + andi t9,a0,3 + bne t9,zero,L(lastb) + andi t9,a1,3 + bne t9,zero,L(lastb) + + PTR_SUBU a3,a2,t8 + PTR_ADDU a3,a0,a3 + +L(wcopy_loop): + lw REG3,0(a1) + PTR_ADDIU a0,a0,4 + PTR_ADDIU a1,a1,4 + bne a0,a3,L(wcopy_loop) + sw REG3,-4(a0) + + b L(lastb) + move a2,t8 + +#ifndef R6_CODE +/* + * UNALIGNED case, got here with a3 = "negu a0" + * This code is nearly identical to the aligned code above + * but only the destination (not the source) gets aligned + * so we need to do partial loads of the source followed + * by normal stores to the destination (once we have aligned + * the destination). + */ + +L(unaligned): + andi a3,a3,(NSIZE-1) /* copy a3 bytes to align a0/a1 */ + beqz a3,L(ua_chk16w) /* if a3=0, it is already aligned */ + PTR_SUBU a2,a2,a3 /* a2 is the remining bytes count */ + + C_LDHI v1,UNIT(0)(a1) + C_LDLO v1,UNITM1(1)(a1) + PTR_ADDU a1,a1,a3 + C_STHI v1,UNIT(0)(a0) + PTR_ADDU a0,a0,a3 + +/* + * Now the destination (but not the source) is aligned + * Set a2 to count how many bytes we have to copy after all the 64/128 byte + * chunks are copied and a3 to the dst pointer after all the 64/128 byte + * chunks have been copied. We will loop, incrementing a0 and a1 until a0 + * equals a3. + */ + +L(ua_chk16w): + andi t8,a2,NSIZEDMASK /* any whole 64-byte/128-byte chunks? */ + beq a2,t8,L(ua_chkw) /* if a2==t8, no 64-byte/128-byte chunks */ + PTR_SUBU a3,a2,t8 /* subtract from a2 the reminder */ + PTR_ADDU a3,a0,a3 /* Now a3 is the final dst after loop */ + +# if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) + PTR_ADDU t0,a0,a2 /* t0 is the "past the end" address */ + PTR_SUBU t9,t0,PREFETCH_LIMIT /* t9 is the "last safe pref" address */ +# endif + PREFETCH_FOR_LOAD (0, a1) + PREFETCH_FOR_LOAD (1, a1) + PREFETCH_FOR_LOAD (2, a1) +# if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE) + PREFETCH_FOR_STORE (1, a0) + PREFETCH_FOR_STORE (2, a0) + PREFETCH_FOR_STORE (3, a0) +# endif +# if defined(RETURN_FIRST_PREFETCH) && defined(USE_PREFETCH) +# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) + sltu v1,t9,a0 + bgtz v1,L(ua_skip_set) + nop + PTR_ADDIU v0,a0,(PREFETCH_CHUNK*4) +L(ua_skip_set): +# else + PTR_ADDIU v0,a0,(PREFETCH_CHUNK*1) +# endif +# endif +L(ua_loop16w): + PREFETCH_FOR_LOAD (3, a1) + C_LDHI t0,UNIT(0)(a1) + C_LDHI t1,UNIT(1)(a1) + C_LDHI REG2,UNIT(2)(a1) +# if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) + sltu v1,t9,a0 + bgtz v1,L(ua_skip_pref) +# endif + C_LDHI REG3,UNIT(3)(a1) + PREFETCH_FOR_STORE (4, a0) + PREFETCH_FOR_STORE (5, a0) +L(ua_skip_pref): + C_LDHI REG4,UNIT(4)(a1) + C_LDHI REG5,UNIT(5)(a1) + C_LDHI REG6,UNIT(6)(a1) + C_LDHI REG7,UNIT(7)(a1) + C_LDLO t0,UNITM1(1)(a1) + C_LDLO t1,UNITM1(2)(a1) + C_LDLO REG2,UNITM1(3)(a1) + C_LDLO REG3,UNITM1(4)(a1) + C_LDLO REG4,UNITM1(5)(a1) + C_LDLO REG5,UNITM1(6)(a1) + C_LDLO REG6,UNITM1(7)(a1) + C_LDLO REG7,UNITM1(8)(a1) + PREFETCH_FOR_LOAD (4, a1) + C_ST t0,UNIT(0)(a0) + C_ST t1,UNIT(1)(a0) + C_ST REG2,UNIT(2)(a0) + C_ST REG3,UNIT(3)(a0) + C_ST REG4,UNIT(4)(a0) + C_ST REG5,UNIT(5)(a0) + C_ST REG6,UNIT(6)(a0) + C_ST REG7,UNIT(7)(a0) + C_LDHI t0,UNIT(8)(a1) + C_LDHI t1,UNIT(9)(a1) + C_LDHI REG2,UNIT(10)(a1) + C_LDHI REG3,UNIT(11)(a1) + C_LDHI REG4,UNIT(12)(a1) + C_LDHI REG5,UNIT(13)(a1) + C_LDHI REG6,UNIT(14)(a1) + C_LDHI REG7,UNIT(15)(a1) + C_LDLO t0,UNITM1(9)(a1) + C_LDLO t1,UNITM1(10)(a1) + C_LDLO REG2,UNITM1(11)(a1) + C_LDLO REG3,UNITM1(12)(a1) + C_LDLO REG4,UNITM1(13)(a1) + C_LDLO REG5,UNITM1(14)(a1) + C_LDLO REG6,UNITM1(15)(a1) + C_LDLO REG7,UNITM1(16)(a1) + PREFETCH_FOR_LOAD (5, a1) + C_ST t0,UNIT(8)(a0) + C_ST t1,UNIT(9)(a0) + C_ST REG2,UNIT(10)(a0) + C_ST REG3,UNIT(11)(a0) + C_ST REG4,UNIT(12)(a0) + C_ST REG5,UNIT(13)(a0) + C_ST REG6,UNIT(14)(a0) + C_ST REG7,UNIT(15)(a0) + PTR_ADDIU a0,a0,UNIT(16) /* adding 64/128 to dest */ + bne a0,a3,L(ua_loop16w) + PTR_ADDIU a1,a1,UNIT(16) /* adding 64/128 to src */ + move a2,t8 + +/* Here we have src and dest word-aligned but less than 64-bytes or + * 128 bytes to go. Check for a 32(64) byte chunk and copy if if there + * is one. Otherwise jump down to L(ua_chk1w) to handle the tail end of + * the copy. */ + +L(ua_chkw): + PREFETCH_FOR_LOAD (0, a1) + andi t8,a2,NSIZEMASK /* Is there a 32-byte/64-byte chunk. */ + /* t8 is the reminder count past 32-bytes */ + beq a2,t8,L(ua_chk1w) /* When a2=t8, no 32-byte chunk */ + nop + C_LDHI t0,UNIT(0)(a1) + C_LDHI t1,UNIT(1)(a1) + C_LDHI REG2,UNIT(2)(a1) + C_LDHI REG3,UNIT(3)(a1) + C_LDHI REG4,UNIT(4)(a1) + C_LDHI REG5,UNIT(5)(a1) + C_LDHI REG6,UNIT(6)(a1) + C_LDHI REG7,UNIT(7)(a1) + C_LDLO t0,UNITM1(1)(a1) + C_LDLO t1,UNITM1(2)(a1) + C_LDLO REG2,UNITM1(3)(a1) + C_LDLO REG3,UNITM1(4)(a1) + C_LDLO REG4,UNITM1(5)(a1) + C_LDLO REG5,UNITM1(6)(a1) + C_LDLO REG6,UNITM1(7)(a1) + C_LDLO REG7,UNITM1(8)(a1) + PTR_ADDIU a1,a1,UNIT(8) + C_ST t0,UNIT(0)(a0) + C_ST t1,UNIT(1)(a0) + C_ST REG2,UNIT(2)(a0) + C_ST REG3,UNIT(3)(a0) + C_ST REG4,UNIT(4)(a0) + C_ST REG5,UNIT(5)(a0) + C_ST REG6,UNIT(6)(a0) + C_ST REG7,UNIT(7)(a0) + PTR_ADDIU a0,a0,UNIT(8) +/* + * Here we have less than 32(64) bytes to copy. Set up for a loop to + * copy one word (or double word) at a time. + */ +L(ua_chk1w): + andi a2,t8,(NSIZE-1) /* a2 is the reminder past one (d)word chunks */ + beq a2,t8,L(ua_smallCopy) + PTR_SUBU a3,t8,a2 /* a3 is count of bytes in one (d)word chunks */ + PTR_ADDU a3,a0,a3 /* a3 is the dst address after loop */ + +/* copying in words (4-byte or 8-byte chunks) */ +L(ua_wordCopy_loop): + C_LDHI v1,UNIT(0)(a1) + C_LDLO v1,UNITM1(1)(a1) + PTR_ADDIU a0,a0,UNIT(1) + PTR_ADDIU a1,a1,UNIT(1) + bne a0,a3,L(ua_wordCopy_loop) + C_ST v1,UNIT(-1)(a0) + +/* Copy the last 8 (or 16) bytes */ +L(ua_smallCopy): + beqz a2,L(leave) + PTR_ADDU a3,a0,a2 /* a3 is the last dst address */ +L(ua_smallCopy_loop): + lb v1,0(a1) + PTR_ADDIU a0,a0,1 + PTR_ADDIU a1,a1,1 + bne a0,a3,L(ua_smallCopy_loop) + sb v1,-1(a0) + + j ra + nop + +#else /* R6_CODE */ + +# ifdef __MIPSEB +# define SWAP_REGS(X,Y) X, Y +# define ALIGN_OFFSET(N) (N) +# else +# define SWAP_REGS(X,Y) Y, X +# define ALIGN_OFFSET(N) (NSIZE-N) +# endif +# define R6_UNALIGNED_WORD_COPY(BYTEOFFSET) \ + andi REG7, a2, (NSIZE-1);/* REG7 is # of bytes to by bytes. */ \ + beq REG7, a2, L(lastb); /* Check for bytes to copy by word */ \ + PTR_SUBU a3, a2, REG7; /* a3 is number of bytes to be copied in */ \ + /* (d)word chunks. */ \ + move a2, REG7; /* a2 is # of bytes to copy byte by byte */ \ + /* after word loop is finished. */ \ + PTR_ADDU REG6, a0, a3; /* REG6 is the dst address after loop. */ \ + PTR_SUBU REG2, a1, t8; /* REG2 is the aligned src address. */ \ + PTR_ADDU a1, a1, a3; /* a1 is addr of source after word loop. */ \ + C_LD t0, UNIT(0)(REG2); /* Load first part of source. */ \ +L(r6_ua_wordcopy##BYTEOFFSET): \ + C_LD t1, UNIT(1)(REG2); /* Load second part of source. */ \ + C_ALIGN REG3, SWAP_REGS(t1,t0), ALIGN_OFFSET(BYTEOFFSET); \ + PTR_ADDIU a0, a0, UNIT(1); /* Increment destination pointer. */ \ + PTR_ADDIU REG2, REG2, UNIT(1); /* Increment aligned source pointer.*/ \ + move t0, t1; /* Move second part of source to first. */ \ + bne a0, REG6,L(r6_ua_wordcopy##BYTEOFFSET); \ + C_ST REG3, UNIT(-1)(a0); \ + j L(lastb); \ + nop + + /* We are generating R6 code, the destination is 4 byte aligned and + the source is not 4 byte aligned. t8 is 1, 2, or 3 depending on the + alignment of the source. */ + +L(r6_unaligned1): + R6_UNALIGNED_WORD_COPY(1) +L(r6_unaligned2): + R6_UNALIGNED_WORD_COPY(2) +L(r6_unaligned3): + R6_UNALIGNED_WORD_COPY(3) +# ifdef USE_DOUBLE +L(r6_unaligned4): + R6_UNALIGNED_WORD_COPY(4) +L(r6_unaligned5): + R6_UNALIGNED_WORD_COPY(5) +L(r6_unaligned6): + R6_UNALIGNED_WORD_COPY(6) +L(r6_unaligned7): + R6_UNALIGNED_WORD_COPY(7) +# endif +#endif /* R6_CODE */ + + .set at + .set reorder +END(MEMCPY_NAME) +#ifndef ANDROID_CHANGES +# ifdef _LIBC +libc_hidden_builtin_def (MEMCPY_NAME) +# endif +#endif diff --git a/REORG.TODO/sysdeps/mips/memset.S b/REORG.TODO/sysdeps/mips/memset.S new file mode 100644 index 0000000000..04370a8660 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/memset.S @@ -0,0 +1,426 @@ +/* Copyright (C) 2013-2017 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/>. */ + +#ifdef ANDROID_CHANGES +# include "machine/asm.h" +# include "machine/regdef.h" +# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE +#elif _LIBC +# include <sysdep.h> +# include <regdef.h> +# include <sys/asm.h> +# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE +#elif defined _COMPILING_NEWLIB +# include "machine/asm.h" +# include "machine/regdef.h" +# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE +#else +# include <regdef.h> +# include <sys/asm.h> +#endif + +/* Check to see if the MIPS architecture we are compiling for supports + prefetching. */ + +#if (__mips == 4) || (__mips == 5) || (__mips == 32) || (__mips == 64) +# ifndef DISABLE_PREFETCH +# define USE_PREFETCH +# endif +#endif + +#if defined(_MIPS_SIM) && ((_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32)) +# ifndef DISABLE_DOUBLE +# define USE_DOUBLE +# endif +#endif + +#ifndef USE_DOUBLE +# ifndef DISABLE_DOUBLE_ALIGN +# define DOUBLE_ALIGN +# endif +#endif + + +/* Some asm.h files do not have the L macro definition. */ +#ifndef L +# if _MIPS_SIM == _ABIO32 +# define L(label) $L ## label +# else +# define L(label) .L ## label +# endif +#endif + +/* Some asm.h files do not have the PTR_ADDIU macro definition. */ +#ifndef PTR_ADDIU +# ifdef USE_DOUBLE +# define PTR_ADDIU daddiu +# else +# define PTR_ADDIU addiu +# endif +#endif + +/* New R6 instructions that may not be in asm.h. */ +#ifndef PTR_LSA +# if _MIPS_SIM == _ABI64 +# define PTR_LSA dlsa +# else +# define PTR_LSA lsa +# endif +#endif + +/* Using PREFETCH_HINT_PREPAREFORSTORE instead of PREFETCH_STORE + or PREFETCH_STORE_STREAMED offers a large performance advantage + but PREPAREFORSTORE has some special restrictions to consider. + + Prefetch with the 'prepare for store' hint does not copy a memory + location into the cache, it just allocates a cache line and zeros + it out. This means that if you do not write to the entire cache + line before writing it out to memory some data will get zero'ed out + when the cache line is written back to memory and data will be lost. + + There are ifdef'ed sections of this memcpy to make sure that it does not + do prefetches on cache lines that are not going to be completely written. + This code is only needed and only used when PREFETCH_STORE_HINT is set to + PREFETCH_HINT_PREPAREFORSTORE. This code assumes that cache lines are + less than MAX_PREFETCH_SIZE bytes and if the cache line is larger it will + not work correctly. */ + +#ifdef USE_PREFETCH +# define PREFETCH_HINT_STORE 1 +# define PREFETCH_HINT_STORE_STREAMED 5 +# define PREFETCH_HINT_STORE_RETAINED 7 +# define PREFETCH_HINT_PREPAREFORSTORE 30 + +/* If we have not picked out what hints to use at this point use the + standard load and store prefetch hints. */ +# ifndef PREFETCH_STORE_HINT +# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE +# endif + +/* We double everything when USE_DOUBLE is true so we do 2 prefetches to + get 64 bytes in that case. The assumption is that each individual + prefetch brings in 32 bytes. */ +# ifdef USE_DOUBLE +# define PREFETCH_CHUNK 64 +# define PREFETCH_FOR_STORE(chunk, reg) \ + pref PREFETCH_STORE_HINT, (chunk)*64(reg); \ + pref PREFETCH_STORE_HINT, ((chunk)*64)+32(reg) +# else +# define PREFETCH_CHUNK 32 +# define PREFETCH_FOR_STORE(chunk, reg) \ + pref PREFETCH_STORE_HINT, (chunk)*32(reg) +# endif + +/* MAX_PREFETCH_SIZE is the maximum size of a prefetch, it must not be less + than PREFETCH_CHUNK, the assumed size of each prefetch. If the real size + of a prefetch is greater than MAX_PREFETCH_SIZE and the PREPAREFORSTORE + hint is used, the code will not work correctly. If PREPAREFORSTORE is not + used than MAX_PREFETCH_SIZE does not matter. */ +# define MAX_PREFETCH_SIZE 128 +/* PREFETCH_LIMIT is set based on the fact that we never use an offset greater + than 5 on a STORE prefetch and that a single prefetch can never be larger + than MAX_PREFETCH_SIZE. We add the extra 32 when USE_DOUBLE is set because + we actually do two prefetches in that case, one 32 bytes after the other. */ +# ifdef USE_DOUBLE +# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + 32 + MAX_PREFETCH_SIZE +# else +# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + MAX_PREFETCH_SIZE +# endif + +# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) \ + && ((PREFETCH_CHUNK * 4) < MAX_PREFETCH_SIZE) +/* We cannot handle this because the initial prefetches may fetch bytes that + are before the buffer being copied. We start copies with an offset + of 4 so avoid this situation when using PREPAREFORSTORE. */ +# error "PREFETCH_CHUNK is too large and/or MAX_PREFETCH_SIZE is too small." +# endif +#else /* USE_PREFETCH not defined */ +# define PREFETCH_FOR_STORE(offset, reg) +#endif + +#if __mips_isa_rev > 5 +# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) +# undef PREFETCH_STORE_HINT +# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE_STREAMED +# endif +# define R6_CODE +#endif + +/* Allow the routine to be named something else if desired. */ +#ifndef MEMSET_NAME +# define MEMSET_NAME memset +#endif + +/* We load/store 64 bits at a time when USE_DOUBLE is true. + The C_ prefix stands for CHUNK and is used to avoid macro name + conflicts with system header files. */ + +#ifdef USE_DOUBLE +# define C_ST sd +# ifdef __MIPSEB +# define C_STHI sdl /* high part is left in big-endian */ +# else +# define C_STHI sdr /* high part is right in little-endian */ +# endif +#else +# define C_ST sw +# ifdef __MIPSEB +# define C_STHI swl /* high part is left in big-endian */ +# else +# define C_STHI swr /* high part is right in little-endian */ +# endif +#endif + +/* Bookkeeping values for 32 vs. 64 bit mode. */ +#ifdef USE_DOUBLE +# define NSIZE 8 +# define NSIZEMASK 0x3f +# define NSIZEDMASK 0x7f +#else +# define NSIZE 4 +# define NSIZEMASK 0x1f +# define NSIZEDMASK 0x3f +#endif +#define UNIT(unit) ((unit)*NSIZE) +#define UNITM1(unit) (((unit)*NSIZE)-1) + +#ifdef ANDROID_CHANGES +LEAF(MEMSET_NAME,0) +#else +LEAF(MEMSET_NAME) +#endif + + .set nomips16 + .set noreorder +/* If the size is less than 2*NSIZE (8 or 16), go to L(lastb). Regardless of + size, copy dst pointer to v0 for the return value. */ + slti t2,a2,(2 * NSIZE) + bne t2,zero,L(lastb) + move v0,a0 + +/* If memset value is not zero, we copy it to all the bytes in a 32 or 64 + bit word. */ + beq a1,zero,L(set0) /* If memset value is zero no smear */ + PTR_SUBU a3,zero,a0 + nop + + /* smear byte into 32 or 64 bit word */ +#if ((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2) +# ifdef USE_DOUBLE + dins a1, a1, 8, 8 /* Replicate fill byte into half-word. */ + dins a1, a1, 16, 16 /* Replicate fill byte into word. */ + dins a1, a1, 32, 32 /* Replicate fill byte into dbl word. */ +# else + ins a1, a1, 8, 8 /* Replicate fill byte into half-word. */ + ins a1, a1, 16, 16 /* Replicate fill byte into word. */ +# endif +#else +# ifdef USE_DOUBLE + and a1,0xff + dsll t2,a1,8 + or a1,t2 + dsll t2,a1,16 + or a1,t2 + dsll t2,a1,32 + or a1,t2 +# else + and a1,0xff + sll t2,a1,8 + or a1,t2 + sll t2,a1,16 + or a1,t2 +# endif +#endif + +/* If the destination address is not aligned do a partial store to get it + aligned. If it is already aligned just jump to L(aligned). */ +L(set0): +#ifndef R6_CODE + andi t2,a3,(NSIZE-1) /* word-unaligned address? */ + beq t2,zero,L(aligned) /* t2 is the unalignment count */ + PTR_SUBU a2,a2,t2 + C_STHI a1,0(a0) + PTR_ADDU a0,a0,t2 +#else /* R6_CODE */ + andi t2,a0,(NSIZE-1) + lapc t9,L(atable) + PTR_LSA t9,t2,t9,2 + jrc t9 +L(atable): + bc L(aligned) +# ifdef USE_DOUBLE + bc L(lb7) + bc L(lb6) + bc L(lb5) + bc L(lb4) +# endif + bc L(lb3) + bc L(lb2) + bc L(lb1) +L(lb7): + sb a1,6(a0) +L(lb6): + sb a1,5(a0) +L(lb5): + sb a1,4(a0) +L(lb4): + sb a1,3(a0) +L(lb3): + sb a1,2(a0) +L(lb2): + sb a1,1(a0) +L(lb1): + sb a1,0(a0) + + li t9,NSIZE + subu t2,t9,t2 + PTR_SUBU a2,a2,t2 + PTR_ADDU a0,a0,t2 +#endif /* R6_CODE */ + +L(aligned): +/* If USE_DOUBLE is not set we may still want to align the data on a 16 + byte boundry instead of an 8 byte boundry to maximize the opportunity + of proAptiv chips to do memory bonding (combining two sequential 4 + byte stores into one 8 byte store). We know there are at least 4 bytes + left to store or we would have jumped to L(lastb) earlier in the code. */ +#ifdef DOUBLE_ALIGN + andi t2,a3,4 + beq t2,zero,L(double_aligned) + PTR_SUBU a2,a2,t2 + sw a1,0(a0) + PTR_ADDU a0,a0,t2 +L(double_aligned): +#endif + +/* Now the destination is aligned to (word or double word) aligned address + Set a2 to count how many bytes we have to copy after all the 64/128 byte + chunks are copied and a3 to the dest pointer after all the 64/128 byte + chunks have been copied. We will loop, incrementing a0 until it equals + a3. */ + andi t8,a2,NSIZEDMASK /* any whole 64-byte/128-byte chunks? */ + beq a2,t8,L(chkw) /* if a2==t8, no 64-byte/128-byte chunks */ + PTR_SUBU a3,a2,t8 /* subtract from a2 the reminder */ + PTR_ADDU a3,a0,a3 /* Now a3 is the final dst after loop */ + +/* When in the loop we may prefetch with the 'prepare to store' hint, + in this case the a0+x should not be past the "t0-32" address. This + means: for x=128 the last "safe" a0 address is "t0-160". Alternatively, + for x=64 the last "safe" a0 address is "t0-96" In the current version we + will use "prefetch hint,128(a0)", so "t0-160" is the limit. */ +#if defined(USE_PREFETCH) \ + && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) + PTR_ADDU t0,a0,a2 /* t0 is the "past the end" address */ + PTR_SUBU t9,t0,PREFETCH_LIMIT /* t9 is the "last safe pref" address */ +#endif +#if defined(USE_PREFETCH) \ + && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE) + PREFETCH_FOR_STORE (1, a0) + PREFETCH_FOR_STORE (2, a0) + PREFETCH_FOR_STORE (3, a0) +#endif + +L(loop16w): +#if defined(USE_PREFETCH) \ + && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) + sltu v1,t9,a0 /* If a0 > t9 don't use next prefetch */ + bgtz v1,L(skip_pref) + nop +#endif +#ifdef R6_CODE + PREFETCH_FOR_STORE (2, a0) +#else + PREFETCH_FOR_STORE (4, a0) + PREFETCH_FOR_STORE (5, a0) +#endif +L(skip_pref): + C_ST a1,UNIT(0)(a0) + C_ST a1,UNIT(1)(a0) + C_ST a1,UNIT(2)(a0) + C_ST a1,UNIT(3)(a0) + C_ST a1,UNIT(4)(a0) + C_ST a1,UNIT(5)(a0) + C_ST a1,UNIT(6)(a0) + C_ST a1,UNIT(7)(a0) + C_ST a1,UNIT(8)(a0) + C_ST a1,UNIT(9)(a0) + C_ST a1,UNIT(10)(a0) + C_ST a1,UNIT(11)(a0) + C_ST a1,UNIT(12)(a0) + C_ST a1,UNIT(13)(a0) + C_ST a1,UNIT(14)(a0) + C_ST a1,UNIT(15)(a0) + PTR_ADDIU a0,a0,UNIT(16) /* adding 64/128 to dest */ + bne a0,a3,L(loop16w) + nop + move a2,t8 + +/* Here we have dest word-aligned but less than 64-bytes or 128 bytes to go. + Check for a 32(64) byte chunk and copy if if there is one. Otherwise + jump down to L(chk1w) to handle the tail end of the copy. */ +L(chkw): + andi t8,a2,NSIZEMASK /* is there a 32-byte/64-byte chunk. */ + /* the t8 is the reminder count past 32-bytes */ + beq a2,t8,L(chk1w)/* when a2==t8, no 32-byte chunk */ + nop + C_ST a1,UNIT(0)(a0) + C_ST a1,UNIT(1)(a0) + C_ST a1,UNIT(2)(a0) + C_ST a1,UNIT(3)(a0) + C_ST a1,UNIT(4)(a0) + C_ST a1,UNIT(5)(a0) + C_ST a1,UNIT(6)(a0) + C_ST a1,UNIT(7)(a0) + PTR_ADDIU a0,a0,UNIT(8) + +/* Here we have less than 32(64) bytes to set. Set up for a loop to + copy one word (or double word) at a time. Set a2 to count how many + bytes we have to copy after all the word (or double word) chunks are + copied and a3 to the dest pointer after all the (d)word chunks have + been copied. We will loop, incrementing a0 until a0 equals a3. */ +L(chk1w): + andi a2,t8,(NSIZE-1) /* a2 is the reminder past one (d)word chunks */ + beq a2,t8,L(lastb) + PTR_SUBU a3,t8,a2 /* a3 is count of bytes in one (d)word chunks */ + PTR_ADDU a3,a0,a3 /* a3 is the dst address after loop */ + +/* copying in words (4-byte or 8 byte chunks) */ +L(wordCopy_loop): + PTR_ADDIU a0,a0,UNIT(1) + bne a0,a3,L(wordCopy_loop) + C_ST a1,UNIT(-1)(a0) + +/* Copy the last 8 (or 16) bytes */ +L(lastb): + blez a2,L(leave) + PTR_ADDU a3,a0,a2 /* a3 is the last dst address */ +L(lastbloop): + PTR_ADDIU a0,a0,1 + bne a0,a3,L(lastbloop) + sb a1,-1(a0) +L(leave): + j ra + nop + + .set at + .set reorder +END(MEMSET_NAME) +#ifndef ANDROID_CHANGES +# ifdef _LIBC +libc_hidden_builtin_def (MEMSET_NAME) +# endif +#endif diff --git a/REORG.TODO/sysdeps/mips/memusage.h b/REORG.TODO/sysdeps/mips/memusage.h new file mode 100644 index 0000000000..aa2d4a8a3a --- /dev/null +++ b/REORG.TODO/sysdeps/mips/memusage.h @@ -0,0 +1,20 @@ +/* Copyright (C) 2000-2017 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/>. */ + +#define GETSP() ({ register uintptr_t stack_ptr asm ("$29"); stack_ptr; }) + +#include <sysdeps/generic/memusage.h> diff --git a/REORG.TODO/sysdeps/mips/mips32/Implies b/REORG.TODO/sysdeps/mips/mips32/Implies new file mode 100644 index 0000000000..6473f2517c --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/Implies @@ -0,0 +1,3 @@ +mips/ieee754 +mips +wordsize-32 diff --git a/REORG.TODO/sysdeps/mips/mips32/Makefile b/REORG.TODO/sysdeps/mips/mips32/Makefile new file mode 100644 index 0000000000..dec0b024c3 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/Makefile @@ -0,0 +1,3 @@ +ifeq ($(filter -mabi=32,$(CC)),) +CC += -mabi=32 +endif diff --git a/REORG.TODO/sysdeps/mips/mips32/crti.S b/REORG.TODO/sysdeps/mips/mips32/crti.S new file mode 100644 index 0000000000..2cfdb23e3e --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/crti.S @@ -0,0 +1,100 @@ +/* Special .init and .fini section support for MIPS (o32). + Copyright (C) 1995-2017 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.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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/>. */ + +/* crti.S puts a function prologue at the beginning of the .init and + .fini sections and defines global symbols for those addresses, so + they can be called as functions. The symbols _init and _fini are + magic and cause the linker to emit DT_INIT and DT_FINI. */ + +#include <libc-symbols.h> + +#ifdef __mips_micromips +# define JALR_RELOC R_MICROMIPS_JALR +#else +# define JALR_RELOC R_MIPS_JALR +#endif + +#ifndef PREINIT_FUNCTION +# define PREINIT_FUNCTION __gmon_start__ +#endif + +#ifndef PREINIT_FUNCTION_WEAK +# define PREINIT_FUNCTION_WEAK 1 +#endif + +#if PREINIT_FUNCTION_WEAK + weak_extern (PREINIT_FUNCTION) +#else + .hidden PREINIT_FUNCTION +#endif + + .set nomips16 + + .section .init,"ax",@progbits + .p2align 2 + .globl _init + .type _init, @function +_init: + .set noreorder + .cpload $25 + .set reorder + addiu $sp,$sp,-32 + .cprestore 16 + sw $31,28($sp) +#if PREINIT_FUNCTION_WEAK + lw $2,%got(PREINIT_FUNCTION)($28) + beq $2,$0,.Lno_weak_fn + lw $25,%call16(PREINIT_FUNCTION)($28) + .reloc 1f,JALR_RELOC,PREINIT_FUNCTION +1: jalr $25 +.Lno_weak_fn: + .insn +#else + lw $25,%got(PREINIT_FUNCTION)($28) + .reloc 1f,JALR_RELOC,PREINIT_FUNCTION +1: jalr $25 +#endif + + .section .fini,"ax",@progbits + .p2align 2 + .globl _fini + .type _fini, @function +_fini: + .set noreorder + .cpload $25 + .set reorder + addiu $sp,$sp,-32 + .cprestore 16 + sw $31,28($sp) diff --git a/REORG.TODO/sysdeps/mips/mips32/crtn.S b/REORG.TODO/sysdeps/mips/mips32/crtn.S new file mode 100644 index 0000000000..6655e2f03c --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/crtn.S @@ -0,0 +1,57 @@ +/* Special .init and .fini section support for MIPS (o32). + Copyright (C) 1995-2017 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.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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/>. */ + +/* crtn.S puts function epilogues in the .init and .fini sections + corresponding to the prologues in crti.S. */ + + .set nomips16 + + .section .init,"ax",@progbits + lw $31,28($sp) + .set noreorder + .set nomacro + j $31 + addiu $sp,$sp,32 + .set macro + .set reorder + + .section .fini,"ax",@progbits + lw $31,28($sp) + .set noreorder + .set nomacro + j $31 + addiu $sp,$sp,32 + .set macro + .set reorder diff --git a/REORG.TODO/sysdeps/mips/mips32/fpu/Makefile b/REORG.TODO/sysdeps/mips/mips32/fpu/Makefile new file mode 100644 index 0000000000..951c408423 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/fpu/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),math) +aux += fpucw-helpers +endif diff --git a/REORG.TODO/sysdeps/mips/mips32/fpu/Versions b/REORG.TODO/sysdeps/mips/mips32/fpu/Versions new file mode 100644 index 0000000000..91bbf564b3 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/fpu/Versions @@ -0,0 +1,5 @@ +libc { + GLIBC_2.18 { + __mips_fpu_getcw; __mips_fpu_setcw; + } +} diff --git a/REORG.TODO/sysdeps/mips/mips32/fpu/e_sqrt.c b/REORG.TODO/sysdeps/mips/mips32/fpu/e_sqrt.c new file mode 100644 index 0000000000..81f4e77697 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/fpu/e_sqrt.c @@ -0,0 +1 @@ +#include <sysdeps/mips/fpu/e_sqrt.c> diff --git a/REORG.TODO/sysdeps/mips/mips32/fpu/e_sqrtf.c b/REORG.TODO/sysdeps/mips/mips32/fpu/e_sqrtf.c new file mode 100644 index 0000000000..fb0700d45c --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/fpu/e_sqrtf.c @@ -0,0 +1 @@ +#include <sysdeps/mips/fpu/e_sqrtf.c> diff --git a/REORG.TODO/sysdeps/mips/mips32/fpu/fix-fp-int-convert-overflow.h b/REORG.TODO/sysdeps/mips/mips32/fpu/fix-fp-int-convert-overflow.h new file mode 100644 index 0000000000..6ed2ec2bbb --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/fpu/fix-fp-int-convert-overflow.h @@ -0,0 +1,38 @@ +/* Fix for conversion of floating point to integer overflow. MIPS version. + Copyright (C) 2015-2017 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 FIX_FP_INT_CONVERT_OVERFLOW_H +#define FIX_FP_INT_CONVERT_OVERFLOW_H 1 + +/* As of GCC 5, the generic libgcc2.c conversions from floating point + to long long may not raise the correct exceptions on overflow (and + may raise spurious "inexact" exceptions even in non-overflow cases, + see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59412>). */ +#define FIX_FLT_LLONG_CONVERT_OVERFLOW 1 +#define FIX_DBL_LLONG_CONVERT_OVERFLOW 1 +#define FIX_LDBL_LLONG_CONVERT_OVERFLOW 0 + +/* As of GCC 5 and binutils 2.25, for MIPS I GCC generates calls to + assembler macros for conversions from floating point to integer + types, and those macros save and restore the whole of FSCR and so + lose exceptions. */ +#define FIX_FLT_LONG_CONVERT_OVERFLOW (__mips == 1) +#define FIX_DBL_LONG_CONVERT_OVERFLOW (__mips == 1) +#define FIX_LDBL_LONG_CONVERT_OVERFLOW 0 + +#endif /* fix-fp-int-convert-overflow.h */ diff --git a/REORG.TODO/sysdeps/mips/mips32/fpu/fpucw-helpers.c b/REORG.TODO/sysdeps/mips/mips32/fpu/fpucw-helpers.c new file mode 100644 index 0000000000..a69107bee2 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/fpu/fpucw-helpers.c @@ -0,0 +1,34 @@ +/* FPU control word handling, MIPS version, needed by MIPS16 callers. + Copyright (C) 1996-2017 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/>. */ + +#include <fpu_control.h> + +fpu_control_t +__mips_fpu_getcw (void) +{ + fpu_control_t cw; + + _FPU_GETCW (cw); + return cw; +} + +void +__mips_fpu_setcw (fpu_control_t cw) +{ + _FPU_SETCW (cw); +} diff --git a/REORG.TODO/sysdeps/mips/mips32/libm-test-ulps b/REORG.TODO/sysdeps/mips/mips32/libm-test-ulps new file mode 100644 index 0000000000..c6ee80095a --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/libm-test-ulps @@ -0,0 +1,1690 @@ +# Begin of automatic generation + +# Maximal error of functions: +Function: "acos": +float: 1 +ifloat: 1 + +Function: "acos_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "acos_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "acos_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "acosh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "acosh_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "acosh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "acosh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "asin": +float: 1 +ifloat: 1 + +Function: "asin_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "asin_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "asin_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "asinh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "asinh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: "asinh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "asinh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: "atan": +float: 1 +ifloat: 1 + +Function: "atan2": +float: 1 +ifloat: 1 + +Function: "atan2_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "atan2_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "atan2_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "atan_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "atan_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "atan_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "atanh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "atanh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: "atanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "atanh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: "cabs": +double: 1 +idouble: 1 + +Function: "cabs_downward": +double: 1 +idouble: 1 + +Function: "cabs_towardzero": +double: 1 +idouble: 1 + +Function: "cabs_upward": +double: 1 +idouble: 1 + +Function: Real part of "cacos": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Imaginary part of "cacos": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Real part of "cacos_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: Imaginary part of "cacos_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 + +Function: Real part of "cacos_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: Imaginary part of "cacos_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 + +Function: Real part of "cacos_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Imaginary part of "cacos_upward": +double: 5 +float: 7 +idouble: 5 +ifloat: 7 + +Function: Real part of "cacosh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Imaginary part of "cacosh": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Real part of "cacosh_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 + +Function: Imaginary part of "cacosh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: Real part of "cacosh_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 + +Function: Imaginary part of "cacosh_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: Real part of "cacosh_upward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 + +Function: Imaginary part of "cacosh_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: "carg": +float: 1 +ifloat: 1 + +Function: "carg_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "carg_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "carg_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Real part of "casin": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Imaginary part of "casin": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Real part of "casin_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: Imaginary part of "casin_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 + +Function: Real part of "casin_towardzero": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 + +Function: Imaginary part of "casin_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 + +Function: Real part of "casin_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: Imaginary part of "casin_upward": +double: 5 +float: 7 +idouble: 5 +ifloat: 7 + +Function: Real part of "casinh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Imaginary part of "casinh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Real part of "casinh_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 + +Function: Imaginary part of "casinh_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: Real part of "casinh_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 + +Function: Imaginary part of "casinh_towardzero": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 + +Function: Real part of "casinh_upward": +double: 5 +float: 7 +idouble: 5 +ifloat: 7 + +Function: Imaginary part of "casinh_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: Real part of "catan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Imaginary part of "catan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Real part of "catan_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Imaginary part of "catan_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Real part of "catan_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Imaginary part of "catan_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Real part of "catan_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Imaginary part of "catan_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: Real part of "catanh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Imaginary part of "catanh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Real part of "catanh_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Imaginary part of "catanh_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Real part of "catanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Imaginary part of "catanh_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Real part of "catanh_upward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 + +Function: Imaginary part of "catanh_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "cbrt": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 + +Function: "cbrt_downward": +double: 4 +float: 1 +idouble: 4 +ifloat: 1 + +Function: "cbrt_towardzero": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 + +Function: "cbrt_upward": +double: 5 +float: 1 +idouble: 5 +ifloat: 1 + +Function: Real part of "ccos": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Imaginary part of "ccos": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Real part of "ccos_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Imaginary part of "ccos_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: Real part of "ccos_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Imaginary part of "ccos_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: Real part of "ccos_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Imaginary part of "ccos_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Real part of "ccosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Imaginary part of "ccosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Real part of "ccosh_downward": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 + +Function: Imaginary part of "ccosh_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: Real part of "ccosh_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 + +Function: Imaginary part of "ccosh_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: Real part of "ccosh_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Imaginary part of "ccosh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Real part of "cexp": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: Imaginary part of "cexp": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Real part of "cexp_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Imaginary part of "cexp_downward": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 + +Function: Real part of "cexp_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Imaginary part of "cexp_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 + +Function: Real part of "cexp_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Imaginary part of "cexp_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Real part of "clog": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: Imaginary part of "clog": +float: 1 +ifloat: 1 + +Function: Real part of "clog10": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 + +Function: Imaginary part of "clog10": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Real part of "clog10_downward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 + +Function: Imaginary part of "clog10_downward": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 + +Function: Real part of "clog10_towardzero": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 + +Function: Imaginary part of "clog10_towardzero": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 + +Function: Real part of "clog10_upward": +double: 6 +float: 5 +idouble: 6 +ifloat: 5 + +Function: Imaginary part of "clog10_upward": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 + +Function: Real part of "clog_downward": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 + +Function: Imaginary part of "clog_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Real part of "clog_towardzero": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 + +Function: Imaginary part of "clog_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 + +Function: Real part of "clog_upward": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 + +Function: Imaginary part of "clog_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "cos": +float: 1 +ifloat: 1 + +Function: "cos_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "cos_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "cos_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "cosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "cosh_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "cosh_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "cosh_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Real part of "cpow": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 + +Function: Imaginary part of "cpow": +float: 2 +ifloat: 2 + +Function: Real part of "cpow_downward": +double: 4 +float: 8 +idouble: 4 +ifloat: 8 + +Function: Imaginary part of "cpow_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Real part of "cpow_towardzero": +double: 4 +float: 8 +idouble: 4 +ifloat: 8 + +Function: Imaginary part of "cpow_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Real part of "cpow_upward": +double: 4 +float: 1 +idouble: 4 +ifloat: 1 + +Function: Imaginary part of "cpow_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Real part of "csin": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Real part of "csin_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: Imaginary part of "csin_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Real part of "csin_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: Imaginary part of "csin_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Real part of "csin_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Imaginary part of "csin_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Real part of "csinh": +float: 1 +ifloat: 1 + +Function: Imaginary part of "csinh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Real part of "csinh_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Imaginary part of "csinh_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: Real part of "csinh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Imaginary part of "csinh_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: Real part of "csinh_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Imaginary part of "csinh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Real part of "csqrt": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Imaginary part of "csqrt": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Real part of "csqrt_downward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 + +Function: Imaginary part of "csqrt_downward": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 + +Function: Real part of "csqrt_towardzero": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 + +Function: Imaginary part of "csqrt_towardzero": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 + +Function: Real part of "csqrt_upward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 + +Function: Imaginary part of "csqrt_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: Real part of "ctan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Imaginary part of "ctan": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: Real part of "ctan_downward": +double: 6 +float: 5 +idouble: 6 +ifloat: 5 + +Function: Imaginary part of "ctan_downward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: Real part of "ctan_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 + +Function: Imaginary part of "ctan_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Real part of "ctan_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: Imaginary part of "ctan_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: Real part of "ctanh": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: Imaginary part of "ctanh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Real part of "ctanh_downward": +double: 4 +float: 1 +idouble: 4 +ifloat: 1 + +Function: Imaginary part of "ctanh_downward": +double: 6 +float: 5 +idouble: 6 +ifloat: 5 + +Function: Real part of "ctanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Imaginary part of "ctanh_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 + +Function: Real part of "ctanh_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: Imaginary part of "ctanh_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: "erf": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "erf_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "erf_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "erf_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "erfc": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: "erfc_downward": +double: 5 +float: 6 +idouble: 5 +ifloat: 6 + +Function: "erfc_towardzero": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 + +Function: "erfc_upward": +double: 5 +float: 6 +idouble: 5 +ifloat: 6 + +Function: "exp": +float: 1 +ifloat: 1 + +Function: "exp10": +double: 2 +idouble: 2 + +Function: "exp10_downward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: "exp10_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: "exp10_upward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: "exp2": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "exp2_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "exp2_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "exp2_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "exp_downward": +double: 1 +idouble: 1 + +Function: "exp_towardzero": +double: 1 +idouble: 1 + +Function: "exp_upward": +double: 1 +idouble: 1 + +Function: "expm1": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "expm1_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "expm1_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "expm1_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "gamma": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 + +Function: "gamma_downward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 + +Function: "gamma_towardzero": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 + +Function: "gamma_upward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 + +Function: "hypot": +double: 1 +idouble: 1 + +Function: "hypot_downward": +double: 1 +idouble: 1 + +Function: "hypot_towardzero": +double: 1 +idouble: 1 + +Function: "hypot_upward": +double: 1 +idouble: 1 + +Function: "j0": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "j0_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: "j0_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: "j0_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: "j1": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "j1_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: "j1_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: "j1_upward": +double: 3 +float: 5 +idouble: 3 +ifloat: 5 + +Function: "jn": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 + +Function: "jn_downward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 + +Function: "jn_towardzero": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 + +Function: "jn_upward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 + +Function: "lgamma": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 + +Function: "lgamma_downward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 + +Function: "lgamma_towardzero": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 + +Function: "lgamma_upward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 + +Function: "log": +float: 1 +ifloat: 1 + +Function: "log10": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "log10_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 + +Function: "log10_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "log10_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "log1p": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "log1p_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "log1p_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "log1p_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "log2": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: "log2_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: "log2_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "log2_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: "log_downward": +float: 2 +ifloat: 2 + +Function: "log_towardzero": +float: 2 +ifloat: 2 + +Function: "log_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "pow": +float: 1 +ifloat: 1 + +Function: "pow10": +double: 2 +idouble: 2 + +Function: "pow10_downward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: "pow10_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: "pow10_upward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: "pow_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "pow_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "pow_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "sin": +float: 1 +ifloat: 1 + +Function: "sin_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "sin_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "sin_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "sincos": +float: 1 +ifloat: 1 + +Function: "sincos_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "sincos_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "sincos_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "sinh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "sinh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: "sinh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "sinh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: "tan": +float: 1 +ifloat: 1 + +Function: "tan_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "tan_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "tan_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "tanh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "tanh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: "tanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "tanh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: "tgamma": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 + +Function: "tgamma_downward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 + +Function: "tgamma_towardzero": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 + +Function: "tgamma_upward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 + +Function: "y0": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: "y0_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: "y0_towardzero": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: "y0_upward": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 + +Function: "y1": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: "y1_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: "y1_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: "y1_upward": +double: 7 +float: 2 +idouble: 7 +ifloat: 2 + +Function: "yn": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: "yn_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: "yn_towardzero": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 + +Function: "yn_upward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 + +# end of automatic generation diff --git a/REORG.TODO/sysdeps/mips/mips32/libm-test-ulps-name b/REORG.TODO/sysdeps/mips/mips32/libm-test-ulps-name new file mode 100644 index 0000000000..d0622692ce --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/libm-test-ulps-name @@ -0,0 +1 @@ +MIPS 32-bit diff --git a/REORG.TODO/sysdeps/mips/mips32/mips16/add_n.c b/REORG.TODO/sysdeps/mips/mips32/mips16/add_n.c new file mode 100644 index 0000000000..fbb4120418 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/mips16/add_n.c @@ -0,0 +1 @@ +#include <stdlib/add_n.c> diff --git a/REORG.TODO/sysdeps/mips/mips32/mips16/addmul_1.c b/REORG.TODO/sysdeps/mips/mips32/mips16/addmul_1.c new file mode 100644 index 0000000000..c0e4a0bd7e --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/mips16/addmul_1.c @@ -0,0 +1 @@ +#include <stdlib/addmul_1.c> diff --git a/REORG.TODO/sysdeps/mips/mips32/mips16/fpu/Makefile b/REORG.TODO/sysdeps/mips/mips32/mips16/fpu/Makefile new file mode 100644 index 0000000000..b58c4eeb0c --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/mips16/fpu/Makefile @@ -0,0 +1,5 @@ +# Building hard-float libm as MIPS16 actually produces larger code size, +# so avoid doing so. +ifeq ($(subdir),math) +sysdep-CFLAGS += -mno-mips16 +endif diff --git a/REORG.TODO/sysdeps/mips/mips32/mips16/lshift.c b/REORG.TODO/sysdeps/mips/mips32/mips16/lshift.c new file mode 100644 index 0000000000..2f945d2c59 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/mips16/lshift.c @@ -0,0 +1 @@ +#include <stdlib/lshift.c> diff --git a/REORG.TODO/sysdeps/mips/mips32/mips16/mul_1.c b/REORG.TODO/sysdeps/mips/mips32/mips16/mul_1.c new file mode 100644 index 0000000000..8e758d6039 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/mips16/mul_1.c @@ -0,0 +1 @@ +#include <stdlib/mul_1.c> diff --git a/REORG.TODO/sysdeps/mips/mips32/mips16/rshift.c b/REORG.TODO/sysdeps/mips/mips32/mips16/rshift.c new file mode 100644 index 0000000000..4e350a0dcb --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/mips16/rshift.c @@ -0,0 +1 @@ +#include <stdlib/rshift.c> diff --git a/REORG.TODO/sysdeps/mips/mips32/mips16/sub_n.c b/REORG.TODO/sysdeps/mips/mips32/mips16/sub_n.c new file mode 100644 index 0000000000..d8b54925b1 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/mips16/sub_n.c @@ -0,0 +1 @@ +#include <stdlib/sub_n.c> diff --git a/REORG.TODO/sysdeps/mips/mips32/mips16/submul_1.c b/REORG.TODO/sysdeps/mips/mips32/mips16/submul_1.c new file mode 100644 index 0000000000..44cadf5cc0 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/mips16/submul_1.c @@ -0,0 +1 @@ +#include <stdlib/submul_1.c> diff --git a/REORG.TODO/sysdeps/mips/mips32/sfp-machine.h b/REORG.TODO/sysdeps/mips/mips32/sfp-machine.h new file mode 100644 index 0000000000..5215655029 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips32/sfp-machine.h @@ -0,0 +1,80 @@ +#define _FP_W_TYPE_SIZE 32 +#define _FP_W_TYPE unsigned long +#define _FP_WS_TYPE signed long +#define _FP_I_TYPE long + +#define _FP_MUL_MEAT_S(R,X,Y) \ + _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) +#define _FP_MUL_MEAT_D(R,X,Y) \ + _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) +#define _FP_MUL_MEAT_Q(R,X,Y) \ + _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) + +#define _FP_MUL_MEAT_DW_S(R,X,Y) \ + _FP_MUL_MEAT_DW_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) +#define _FP_MUL_MEAT_DW_D(R,X,Y) \ + _FP_MUL_MEAT_DW_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) +#define _FP_MUL_MEAT_DW_Q(R,X,Y) \ + _FP_MUL_MEAT_DW_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) + +#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(S,R,X,Y) +#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y) +#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y) + +#ifdef __mips_nan2008 +# define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1) +# define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1 +# define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1 +#else +# define _FP_NANFRAC_S (_FP_QNANBIT_S - 1) +# define _FP_NANFRAC_D (_FP_QNANBIT_D - 1), -1 +# define _FP_NANFRAC_Q (_FP_QNANBIT_Q - 1), -1, -1, -1 +#endif +#define _FP_NANSIGN_S 0 +#define _FP_NANSIGN_D 0 +#define _FP_NANSIGN_Q 0 + +#define _FP_KEEPNANFRACP 1 +#ifdef __mips_nan2008 +# define _FP_QNANNEGATEDP 0 +#else +# define _FP_QNANNEGATEDP 1 +#endif + +#ifdef __mips_nan2008 +/* NaN payloads should be preserved for NAN2008. */ +# define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ + do \ + { \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc (R, X); \ + R##_c = FP_CLS_NAN; \ + } \ + while (0) +#else +/* From my experiments it seems X is chosen unless one of the + NaNs is sNaN, in which case the result is NANSIGN/NANFRAC. */ +# define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ + do { \ + if ((_FP_FRAC_HIGH_RAW_##fs(X) | \ + _FP_FRAC_HIGH_RAW_##fs(Y)) & _FP_QNANBIT_##fs) \ + { \ + R##_s = _FP_NANSIGN_##fs; \ + _FP_FRAC_SET_##wc(R,_FP_NANFRAC_##fs); \ + } \ + else \ + { \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc(R,X); \ + } \ + R##_c = FP_CLS_NAN; \ + } while (0) +#endif + +#define FP_EX_INVALID (1 << 4) +#define FP_EX_DIVZERO (1 << 3) +#define FP_EX_OVERFLOW (1 << 2) +#define FP_EX_UNDERFLOW (1 << 1) +#define FP_EX_INEXACT (1 << 0) + +#define _FP_TININESS_AFTER_ROUNDING 1 diff --git a/REORG.TODO/sysdeps/mips/mips64/Implies b/REORG.TODO/sysdeps/mips/mips64/Implies new file mode 100644 index 0000000000..b476b8b298 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/Implies @@ -0,0 +1,5 @@ +# MIPS uses IEEE 754 floating point. +mips/ieee754 +ieee754/flt-32 +ieee754/dbl-64/wordsize-64 +ieee754/dbl-64 diff --git a/REORG.TODO/sysdeps/mips/mips64/Makefile b/REORG.TODO/sysdeps/mips/mips64/Makefile new file mode 100644 index 0000000000..ada13e8b70 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),math) +CPPFLAGS += -I../soft-fp +endif diff --git a/REORG.TODO/sysdeps/mips/mips64/Versions b/REORG.TODO/sysdeps/mips/mips64/Versions new file mode 100644 index 0000000000..253a65f04e --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/Versions @@ -0,0 +1,7 @@ +libm { + GLIBC_2.1 { + # A generic bug got this omitted from other configurations' version + # sets, but we always had it. + exp2l; + } +} diff --git a/REORG.TODO/sysdeps/mips/mips64/__longjmp.c b/REORG.TODO/sysdeps/mips/mips64/__longjmp.c new file mode 100644 index 0000000000..3f96e8e2d4 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/__longjmp.c @@ -0,0 +1,95 @@ +/* Copyright (C) 1992-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Brendan Kehoe (brendan@zen.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, see + <http://www.gnu.org/licenses/>. */ + +#include <setjmp.h> +#include <sgidefs.h> +#include <stdlib.h> + +#ifndef __GNUC__ + #error This file uses GNU C extensions; you must compile with GCC. +#endif + +void +__longjmp (__jmp_buf env_arg, int val_arg) +{ + /* gcc 1.39.19 miscompiled the longjmp routine (as it did setjmp before + the hack around it); force it to use $a1 for the longjmp value. + Without this it saves $a1 in a register which gets clobbered + along the way. */ + register struct __jmp_buf_internal_tag *env asm ("a0"); + register int val asm ("a1"); +#ifdef CHECK_SP + register long long sp asm ("$29"); + CHECK_SP (env[0].__sp, sp, long long); +#endif + +#ifdef __mips_hard_float + /* Pull back the floating point callee-saved registers. */ +#if _MIPS_SIM == _ABI64 + asm volatile ("l.d $f24, %0" : : "m" (env[0].__fpregs[0])); + asm volatile ("l.d $f25, %0" : : "m" (env[0].__fpregs[1])); + asm volatile ("l.d $f26, %0" : : "m" (env[0].__fpregs[2])); + asm volatile ("l.d $f27, %0" : : "m" (env[0].__fpregs[3])); + asm volatile ("l.d $f28, %0" : : "m" (env[0].__fpregs[4])); + asm volatile ("l.d $f29, %0" : : "m" (env[0].__fpregs[5])); + asm volatile ("l.d $f30, %0" : : "m" (env[0].__fpregs[6])); + asm volatile ("l.d $f31, %0" : : "m" (env[0].__fpregs[7])); +#else + asm volatile ("l.d $f20, %0" : : "m" (env[0].__fpregs[0])); + asm volatile ("l.d $f22, %0" : : "m" (env[0].__fpregs[1])); + asm volatile ("l.d $f24, %0" : : "m" (env[0].__fpregs[2])); + asm volatile ("l.d $f26, %0" : : "m" (env[0].__fpregs[3])); + asm volatile ("l.d $f28, %0" : : "m" (env[0].__fpregs[4])); + asm volatile ("l.d $f30, %0" : : "m" (env[0].__fpregs[5])); +#endif +#endif + + /* Get the GP. */ + asm volatile ("ld $gp, %0" : : "m" (env[0].__gp)); + + /* Get the callee-saved registers. */ + asm volatile ("ld $16, %0" : : "m" (env[0].__regs[0])); + asm volatile ("ld $17, %0" : : "m" (env[0].__regs[1])); + asm volatile ("ld $18, %0" : : "m" (env[0].__regs[2])); + asm volatile ("ld $19, %0" : : "m" (env[0].__regs[3])); + asm volatile ("ld $20, %0" : : "m" (env[0].__regs[4])); + asm volatile ("ld $21, %0" : : "m" (env[0].__regs[5])); + asm volatile ("ld $22, %0" : : "m" (env[0].__regs[6])); + asm volatile ("ld $23, %0" : : "m" (env[0].__regs[7])); + + /* Get the PC. */ + asm volatile ("ld $31, %0" : : "m" (env[0].__pc)); + + + /* Restore the stack pointer and the FP. They have to be restored + last and in a single asm as gcc, depending on options used, may + use either of them to access env. */ + asm volatile ("ld $29, %0\n\t" + "ld $30, %1\n\t" : : "m" (env[0].__sp), "m" (env[0].__fp)); + +/* Give setjmp 1 if given a 0, or what they gave us if non-zero. */ + if (val == 0) + asm volatile ("dli $2, 1"); + else + asm volatile ("move $2, %0" : : "r" (val)); + + asm volatile ("j $31"); + + /* Avoid `volatile function does return' warnings. */ + for (;;); +} diff --git a/REORG.TODO/sysdeps/mips/mips64/add_n.S b/REORG.TODO/sysdeps/mips/mips64/add_n.S new file mode 100644 index 0000000000..60033e3e3e --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/add_n.S @@ -0,0 +1,125 @@ +/* MIPS3 __mpn_add_n -- Add two limb vectors of the same length > 0 and + * store sum in a third limb vector. + * + * Copyright (C) 1995-2017 Free Software Foundation, Inc. + * + * This file is part of the GNU MP Library. + * + * The GNU MP Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The GNU MP Library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the GNU MP Library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <sysdep.h> +#include <sys/asm.h> + +/* + * INPUT PARAMETERS + * res_ptr $4 + * s1_ptr $5 + * s2_ptr $6 + * size $7 + */ +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__mpn_add_n) +#ifdef __PIC__ + SETUP_GP /* ??? unused */ +#endif + .set noreorder + .set nomacro + + ld $10,0($5) + ld $11,0($6) + + daddiu $7,$7,-1 + and $9,$7,4-1 # number of limbs in first loop + beq $9,$0,L(L0) # if multiple of 4 limbs, skip first loop + move $2,$0 + + dsubu $7,$7,$9 + +L(Loop0): daddiu $9,$9,-1 + ld $12,8($5) + daddu $11,$11,$2 + ld $13,8($6) + sltu $8,$11,$2 + daddu $11,$10,$11 + sltu $2,$11,$10 + sd $11,0($4) + or $2,$2,$8 + + daddiu $5,$5,8 + daddiu $6,$6,8 + move $10,$12 + move $11,$13 + bne $9,$0,L(Loop0) + daddiu $4,$4,8 + +L(L0): beq $7,$0,L(Lend) + nop + +L(Loop): daddiu $7,$7,-4 + + ld $12,8($5) + daddu $11,$11,$2 + ld $13,8($6) + sltu $8,$11,$2 + daddu $11,$10,$11 + sltu $2,$11,$10 + sd $11,0($4) + or $2,$2,$8 + + ld $10,16($5) + daddu $13,$13,$2 + ld $11,16($6) + sltu $8,$13,$2 + daddu $13,$12,$13 + sltu $2,$13,$12 + sd $13,8($4) + or $2,$2,$8 + + ld $12,24($5) + daddu $11,$11,$2 + ld $13,24($6) + sltu $8,$11,$2 + daddu $11,$10,$11 + sltu $2,$11,$10 + sd $11,16($4) + or $2,$2,$8 + + ld $10,32($5) + daddu $13,$13,$2 + ld $11,32($6) + sltu $8,$13,$2 + daddu $13,$12,$13 + sltu $2,$13,$12 + sd $13,24($4) + or $2,$2,$8 + + daddiu $5,$5,32 + daddiu $6,$6,32 + + bne $7,$0,L(Loop) + daddiu $4,$4,32 + +L(Lend): daddu $11,$11,$2 + sltu $8,$11,$2 + daddu $11,$10,$11 + sltu $2,$11,$10 + sd $11,0($4) + j $31 + or $2,$2,$8 + +END (__mpn_add_n) diff --git a/REORG.TODO/sysdeps/mips/mips64/addmul_1.S b/REORG.TODO/sysdeps/mips/mips64/addmul_1.S new file mode 100644 index 0000000000..9791a08a4d --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/addmul_1.S @@ -0,0 +1,131 @@ +/* MIPS3 __mpn_addmul_1 -- Multiply a limb vector with a single limb and + * add the product to a second limb vector. + * + * Copyright (C) 1992-2017 Free Software Foundation, Inc. + * + * This file is part of the GNU MP Library. + * + * The GNU MP Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The GNU MP Library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the GNU MP Library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <sysdep.h> +#include <sys/asm.h> + +/* INPUT PARAMETERS + * res_ptr $4 + * s1_ptr $5 + * size $6 + * s2_limb $7 + */ + +#ifdef PIC + .option pic2 +#endif +ENTRY (__mpn_addmul_1) +#ifdef PIC + SETUP_GP /* ??? unused */ +#endif + .set noreorder + .set nomacro + + # warm up phase 0 + ld $8,0($5) + + # warm up phase 1 + daddiu $5,$5,8 +#if __mips_isa_rev < 6 + dmultu $8,$7 +#else + dmulu $11,$8,$7 + dmuhu $12,$8,$7 +#endif + + daddiu $6,$6,-1 + beq $6,$0,L(LC0) + move $2,$0 # zero cy2 + + daddiu $6,$6,-1 + beq $6,$0,L(LC1) + ld $8,0($5) # load new s1 limb as early as possible + +L(Loop): ld $10,0($4) +#if __mips_isa_rev < 6 + mflo $3 + mfhi $9 +#else + move $3,$11 + move $9,$12 +#endif + daddiu $5,$5,8 + daddu $3,$3,$2 # add old carry limb to low product limb +#if __mips_isa_rev < 6 + dmultu $8,$7 +#else + dmulu $11,$8,$7 + dmuhu $12,$8,$7 +#endif + ld $8,0($5) # load new s1 limb as early as possible + daddiu $6,$6,-1 # decrement loop counter + sltu $2,$3,$2 # carry from previous addition -> $2 + daddu $3,$10,$3 + sltu $10,$3,$10 + daddu $2,$2,$10 + sd $3,0($4) + daddiu $4,$4,8 + bne $6,$0,L(Loop) + daddu $2,$9,$2 # add high product limb and carry from addition + + # cool down phase 1 +L(LC1): ld $10,0($4) +#if __mips_isa_rev < 6 + mflo $3 + mfhi $9 +#else + move $3,$11 + move $9,$12 +#endif + daddu $3,$3,$2 + sltu $2,$3,$2 +#if __mips_isa_rev < 6 + dmultu $8,$7 +#else + dmulu $11,$8,$7 + dmuhu $12,$8,$7 +#endif + daddu $3,$10,$3 + sltu $10,$3,$10 + daddu $2,$2,$10 + sd $3,0($4) + daddiu $4,$4,8 + daddu $2,$9,$2 # add high product limb and carry from addition + + # cool down phase 0 +L(LC0): ld $10,0($4) +#if __mips_isa_rev < 6 + mflo $3 + mfhi $9 +#else + move $3,$11 + move $9,$12 +#endif + daddu $3,$3,$2 + sltu $2,$3,$2 + daddu $3,$10,$3 + sltu $10,$3,$10 + daddu $2,$2,$10 + sd $3,0($4) + j $31 + daddu $2,$9,$2 # add high product limb and carry from addition + +END (__mpn_addmul_1) diff --git a/REORG.TODO/sysdeps/mips/mips64/bsd-_setjmp.S b/REORG.TODO/sysdeps/mips/mips64/bsd-_setjmp.S new file mode 100644 index 0000000000..a8f27d2de0 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/bsd-_setjmp.S @@ -0,0 +1,47 @@ +/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. MIPS64 version. + Copyright (C) 1996-2017 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/>. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 0)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sgidefs.h> +#include <sysdep.h> +#include <sys/asm.h> + +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (_setjmp) +#ifdef __PIC__ + SETUP_GP +#endif + SETUP_GP64_REG (v0, C_SYMBOL_NAME (_setjmp)) + PTR_LA t9, C_SYMBOL_NAME (__sigsetjmp) +#if _MIPS_SIM == _ABIO32 + nop +#endif + RESTORE_GP64_REG + move a1, zero /* Pass a second argument of zero. */ +#ifdef __PIC__ + jr t9 +#else + j C_SYMBOL_NAME (__sigsetjmp) +#endif +END (_setjmp) +libc_hidden_def (_setjmp) diff --git a/REORG.TODO/sysdeps/mips/mips64/bsd-setjmp.S b/REORG.TODO/sysdeps/mips/mips64/bsd-setjmp.S new file mode 100644 index 0000000000..aeac200f70 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/bsd-setjmp.S @@ -0,0 +1,46 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. MIPS64 version. + Copyright (C) 1996-2017 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/>. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 1)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sgidefs.h> +#include <sysdep.h> +#include <sys/asm.h> + +#ifdef PIC + .option pic2 +#endif +ENTRY (setjmp) +#ifdef __PIC__ + SETUP_GP +#endif + SETUP_GP64_REG (v0, C_SYMBOL_NAME (setjmp)) + PTR_LA t9, C_SYMBOL_NAME (__sigsetjmp) +#if _MIPS_SIM == _ABIO32 + nop +#endif + RESTORE_GP64_REG + dli a1, 1 /* Pass a second argument of one. */ +#ifdef __PIC__ + jr t9 +#else + j C_SYMBOL_NAME (__sigsetjmp) +#endif +END (setjmp) diff --git a/REORG.TODO/sysdeps/mips/mips64/e_sqrtl.c b/REORG.TODO/sysdeps/mips/mips64/e_sqrtl.c new file mode 100644 index 0000000000..3f0829e1b2 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/e_sqrtl.c @@ -0,0 +1,39 @@ +/* long double square root in software floating-point emulation. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson (rth@cygnus.com) and + Jakub Jelinek (jj@ultra.linux.cz). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 <stdlib.h> +#include <soft-fp.h> +#include <quad.h> + +long double +__ieee754_sqrtl (const long double a) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(C); + long double c; + + FP_INIT_ROUNDMODE; + FP_UNPACK_Q(A, a); + FP_SQRT_Q(C, A); + FP_PACK_Q(c, C); + FP_HANDLE_EXCEPTIONS; + return c; +} +strong_alias (__ieee754_sqrtl, __sqrtl_finite) diff --git a/REORG.TODO/sysdeps/mips/mips64/gmp-mparam.h b/REORG.TODO/sysdeps/mips/mips64/gmp-mparam.h new file mode 100644 index 0000000000..f164ce999e --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/gmp-mparam.h @@ -0,0 +1,30 @@ +/* gmp-mparam.h -- Compiler/machine parameter header file. + +Copyright (C) 1991-2017 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library. If not, see <http://www.gnu.org/licenses/>. */ + +#if defined __GMP_H__ && ! defined _LONG_LONG_LIMB +#error "Included too late for _LONG_LONG_LIMB to take effect" +#endif + +#define _LONG_LONG_LIMB +#define BITS_PER_MP_LIMB 64 +#define BYTES_PER_MP_LIMB 8 +#define BITS_PER_LONGINT __WORDSIZE +#define BITS_PER_INT 32 +#define BITS_PER_SHORTINT 16 +#define BITS_PER_CHAR 8 diff --git a/REORG.TODO/sysdeps/mips/mips64/libm-test-ulps b/REORG.TODO/sysdeps/mips/mips64/libm-test-ulps new file mode 100644 index 0000000000..b3b0140abc --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/libm-test-ulps @@ -0,0 +1,2270 @@ +# Begin of automatic generation + +# Maximal error of functions: +Function: "acos": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "acos_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "acos_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "acos_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "acosh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "acosh_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "acosh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "acosh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "asin": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "asin_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "asin_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "asin_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "asinh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "asinh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "asinh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "asinh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "atan": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "atan2": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "atan2_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "atan2_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "atan2_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "atan_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "atan_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "atan_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "atanh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "atanh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "atanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "atanh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "cabs": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "cabs_downward": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "cabs_towardzero": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "cabs_upward": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "cacos": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "cacos": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cacos_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "cacos_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Real part of "cacos_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "cacos_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: Real part of "cacos_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "cacos_upward": +double: 5 +float: 7 +idouble: 5 +ifloat: 7 +ildouble: 7 +ldouble: 7 + +Function: Real part of "cacosh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "cacosh": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cacosh_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "cacosh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: Real part of "cacosh_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "cacosh_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "cacosh_upward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "cacosh_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "carg": +float: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "carg_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "carg_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "carg_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "casin": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "casin": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "casin_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "casin_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Real part of "casin_towardzero": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "casin_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: Real part of "casin_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "casin_upward": +double: 5 +float: 7 +idouble: 5 +ifloat: 7 +ildouble: 7 +ldouble: 7 + +Function: Real part of "casinh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "casinh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "casinh_downward": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "casinh_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "casinh_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "casinh_towardzero": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Real part of "casinh_upward": +double: 5 +float: 7 +idouble: 5 +ifloat: 7 +ildouble: 7 +ldouble: 7 + +Function: Imaginary part of "casinh_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "catan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "catan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "catan_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "catan_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "catan_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "catan_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "catan_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "catan_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: Real part of "catanh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "catanh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "catanh_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "catanh_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "catanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "catanh_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "catanh_upward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "catanh_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "cbrt": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "cbrt_downward": +double: 4 +float: 1 +idouble: 4 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "cbrt_towardzero": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "cbrt_upward": +double: 5 +float: 1 +idouble: 5 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "ccos": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "ccos": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "ccos_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "ccos_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ccos_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "ccos_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ccos_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "ccos_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ccosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "ccosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "ccosh_downward": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "ccosh_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ccosh_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "ccosh_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "ccosh_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "ccosh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cexp": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "cexp": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: Real part of "cexp_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "cexp_downward": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cexp_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "cexp_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cexp_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "cexp_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "clog": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "clog": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "clog10": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "clog10": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "clog10_downward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "clog10_downward": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: Real part of "clog10_towardzero": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "clog10_towardzero": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: Real part of "clog10_upward": +double: 6 +float: 5 +idouble: 6 +ifloat: 5 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "clog10_upward": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: Real part of "clog_downward": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "clog_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "clog_towardzero": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "clog_towardzero": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "clog_upward": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "clog_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "cos": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "cos_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "cos_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "cos_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "cosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "cosh_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 2 + +Function: "cosh_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 2 + +Function: "cosh_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 3 + +Function: Real part of "cpow": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "cpow": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: Real part of "cpow_downward": +double: 4 +float: 8 +idouble: 4 +ifloat: 8 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "cpow_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cpow_towardzero": +double: 4 +float: 8 +idouble: 4 +ifloat: 8 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "cpow_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cpow_upward": +double: 4 +float: 1 +idouble: 4 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "cpow_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csin": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "csin": +ildouble: 1 +ldouble: 1 + +Function: Real part of "csin_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "csin_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csin_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "csin_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csin_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "csin_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "csinh": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "csinh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "csinh_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "csinh_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csinh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "csinh_towardzero": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csinh_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "csinh_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csqrt": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "csqrt": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csqrt_downward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "csqrt_downward": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: Real part of "csqrt_towardzero": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "csqrt_towardzero": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: Real part of "csqrt_upward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "csqrt_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: Real part of "ctan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "ctan": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Real part of "ctan_downward": +double: 6 +float: 5 +idouble: 6 +ifloat: 5 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "ctan_downward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 5 +ldouble: 5 + +Function: Real part of "ctan_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: Imaginary part of "ctan_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Real part of "ctan_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "ctan_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: Real part of "ctanh": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "ctanh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: Real part of "ctanh_downward": +double: 4 +float: 1 +idouble: 4 +ifloat: 1 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "ctanh_downward": +double: 6 +float: 5 +idouble: 6 +ifloat: 5 +ildouble: 4 +ldouble: 4 + +Function: Real part of "ctanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "ctanh_towardzero": +double: 5 +float: 3 +idouble: 5 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: Real part of "ctanh_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "ctanh_upward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: "erf": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "erf_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "erf_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "erf_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "erfc": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "erfc_downward": +double: 5 +float: 6 +idouble: 5 +ifloat: 6 +ildouble: 5 +ldouble: 5 + +Function: "erfc_towardzero": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: "erfc_upward": +double: 5 +float: 6 +idouble: 5 +ifloat: 6 +ildouble: 5 +ldouble: 5 + +Function: "exp": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "exp10": +double: 2 +idouble: 2 +ildouble: 2 +ldouble: 2 + +Function: "exp10_downward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "exp10_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "exp10_upward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "exp2": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "exp2_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "exp2_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "exp2_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "exp_downward": +double: 1 +idouble: 1 + +Function: "exp_towardzero": +double: 1 +idouble: 1 + +Function: "exp_upward": +double: 1 +idouble: 1 + +Function: "expm1": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "expm1_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "expm1_towardzero": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "expm1_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "gamma": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "gamma_downward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 8 +ldouble: 8 + +Function: "gamma_towardzero": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "gamma_upward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 8 +ldouble: 8 + +Function: "hypot": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "hypot_downward": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "hypot_towardzero": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "hypot_upward": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "j0": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "j0_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "j0_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "j0_upward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: "j1": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "j1_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "j1_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "j1_upward": +double: 3 +float: 5 +idouble: 3 +ifloat: 5 +ildouble: 3 +ldouble: 3 + +Function: "jn": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 7 +ldouble: 7 + +Function: "jn_downward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 8 +ldouble: 8 + +Function: "jn_towardzero": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 8 +ldouble: 8 + +Function: "jn_upward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 7 +ldouble: 7 + +Function: "lgamma": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "lgamma_downward": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 8 +ldouble: 8 + +Function: "lgamma_towardzero": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "lgamma_upward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 8 +ldouble: 8 + +Function: "log": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "log10": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "log10_downward": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 1 +ldouble: 1 + +Function: "log10_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "log10_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "log1p": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "log1p_downward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "log1p_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "log1p_upward": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "log2": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "log2_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: "log2_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "log2_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 1 +ldouble: 1 + +Function: "log_downward": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "log_towardzero": +float: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "log_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "pow": +float: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "pow10": +double: 2 +idouble: 2 +ildouble: 2 +ldouble: 2 + +Function: "pow10_downward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "pow10_towardzero": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "pow10_upward": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "pow_downward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "pow_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "pow_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "sin": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "sin_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "sin_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "sin_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "sincos": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "sincos_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "sincos_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "sincos_upward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "sinh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "sinh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: "sinh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "sinh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "tan": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "tan_downward": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "tan_towardzero": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "tan_upward": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "tanh": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "tanh_downward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 4 +ldouble: 4 + +Function: "tanh_towardzero": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "tanh_upward": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: "tgamma": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: "tgamma_downward": +double: 5 +float: 5 +idouble: 5 +ifloat: 5 +ildouble: 5 +ldouble: 5 + +Function: "tgamma_towardzero": +double: 5 +float: 4 +idouble: 5 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +Function: "tgamma_upward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 4 +ldouble: 4 + +Function: "y0": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 3 +ldouble: 3 + +Function: "y0_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "y0_towardzero": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 3 +ldouble: 3 + +Function: "y0_upward": +double: 3 +float: 4 +idouble: 3 +ifloat: 4 +ildouble: 3 +ldouble: 3 + +Function: "y1": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "y1_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +Function: "y1_towardzero": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: "y1_upward": +double: 7 +float: 2 +idouble: 7 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: "yn": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: "yn_downward": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 5 +ldouble: 5 + +Function: "yn_towardzero": +double: 3 +float: 3 +idouble: 3 +ifloat: 3 +ildouble: 5 +ldouble: 5 + +Function: "yn_upward": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 +ildouble: 5 +ldouble: 5 + +# end of automatic generation diff --git a/REORG.TODO/sysdeps/mips/mips64/libm-test-ulps-name b/REORG.TODO/sysdeps/mips/mips64/libm-test-ulps-name new file mode 100644 index 0000000000..916e314f86 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/libm-test-ulps-name @@ -0,0 +1 @@ +MIPS 64-bit diff --git a/REORG.TODO/sysdeps/mips/mips64/lshift.S b/REORG.TODO/sysdeps/mips/mips64/lshift.S new file mode 100644 index 0000000000..7f2e5669a5 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/lshift.S @@ -0,0 +1,100 @@ +/* MIPS3 __mpn_lshift -- + * + * Copyright (C) 1995-2017 Free Software Foundation, Inc. + * + * This file is part of the GNU MP Library. + * + * The GNU MP Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The GNU MP Library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the GNU MP Library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <sysdep.h> +#include <sys/asm.h> + +/* INPUT PARAMETERS + * res_ptr $4 + * src_ptr $5 + * size $6 + * cnt $7 + */ + +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__mpn_lshift) +#ifdef __PIC__ + SETUP_GP /* ??? unused */ +#endif + .set noreorder + .set nomacro + + dsll $2,$6,3 + daddu $5,$5,$2 # make r5 point at end of src + ld $10,-8($5) # load first limb + dsubu $13,$0,$7 + daddu $4,$4,$2 # make r4 point at end of res + daddiu $6,$6,-1 + and $9,$6,4-1 # number of limbs in first loop + beq $9,$0,L(L0) # if multiple of 4 limbs, skip first loop + dsrl $2,$10,$13 # compute function result + + dsubu $6,$6,$9 + +L(Loop0): ld $3,-16($5) + daddiu $4,$4,-8 + daddiu $5,$5,-8 + daddiu $9,$9,-1 + dsll $11,$10,$7 + dsrl $12,$3,$13 + move $10,$3 + or $8,$11,$12 + bne $9,$0,L(Loop0) + sd $8,0($4) + +L(L0): beq $6,$0,L(Lend) + nop + +L(Loop): ld $3,-16($5) + daddiu $4,$4,-32 + daddiu $6,$6,-4 + dsll $11,$10,$7 + dsrl $12,$3,$13 + + ld $10,-24($5) + dsll $14,$3,$7 + or $8,$11,$12 + sd $8,24($4) + dsrl $9,$10,$13 + + ld $3,-32($5) + dsll $11,$10,$7 + or $8,$14,$9 + sd $8,16($4) + dsrl $12,$3,$13 + + ld $10,-40($5) + dsll $14,$3,$7 + or $8,$11,$12 + sd $8,8($4) + dsrl $9,$10,$13 + + daddiu $5,$5,-32 + or $8,$14,$9 + bgtz $6,L(Loop) + sd $8,0($4) + +L(Lend): dsll $8,$10,$7 + j $31 + sd $8,-8($4) +END (__mpn_lshift) diff --git a/REORG.TODO/sysdeps/mips/mips64/mul_1.S b/REORG.TODO/sysdeps/mips/mips64/mul_1.S new file mode 100644 index 0000000000..9ceb683d08 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/mul_1.S @@ -0,0 +1,120 @@ +/* MIPS3 __mpn_mul_1 -- Multiply a limb vector with a single limb and + * store the product in a second limb vector. + * + * Copyright (C) 1992-2017 Free Software Foundation, Inc. + * + * This file is part of the GNU MP Library. + * + * The GNU MP Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The GNU MP Library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the GNU MP Library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <sysdep.h> +#include <sys/asm.h> + +/* INPUT PARAMETERS + * res_ptr $4 + * s1_ptr $5 + * size $6 + * s2_limb $7 + */ + +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__mpn_mul_1) +#ifdef __PIC__ + SETUP_GP /* ??? unused */ +#endif + .set noreorder + .set nomacro + + # warm up phase 0 + ld $8,0($5) + + # warm up phase 1 + daddiu $5,$5,8 +#if __mips_isa_rev < 6 + dmultu $8,$7 +#else + dmulu $11,$8,$7 + dmuhu $12,$8,$7 +#endif + + daddiu $6,$6,-1 + beq $6,$0,L(LC0) + move $2,$0 # zero cy2 + + daddiu $6,$6,-1 + beq $6,$0,L(LC1) + ld $8,0($5) # load new s1 limb as early as possible + +#if __mips_isa_rev < 6 +L(Loop): mflo $10 + mfhi $9 +#else +L(Loop): move $10,$11 + move $9,$12 +#endif + daddiu $5,$5,8 + daddu $10,$10,$2 # add old carry limb to low product limb +#if __mips_isa_rev < 6 + dmultu $8,$7 +#else + dmulu $11,$8,$7 + dmuhu $12,$8,$7 +#endif + ld $8,0($5) # load new s1 limb as early as possible + daddiu $6,$6,-1 # decrement loop counter + sltu $2,$10,$2 # carry from previous addition -> $2 + sd $10,0($4) + daddiu $4,$4,8 + bne $6,$0,L(Loop) + daddu $2,$9,$2 # add high product limb and carry from addition + + # cool down phase 1 +#if __mips_isa_rev < 6 +L(LC1): mflo $10 + mfhi $9 +#else +L(LC1): move $10,$11 + move $9,$12 +#endif + daddu $10,$10,$2 + sltu $2,$10,$2 +#if __mips_isa_rev < 6 + dmultu $8,$7 +#else + dmulu $11,$8,$7 + dmuhu $12,$8,$7 +#endif + sd $10,0($4) + daddiu $4,$4,8 + daddu $2,$9,$2 # add high product limb and carry from addition + + # cool down phase 0 +#if __mips_isa_rev < 6 +L(LC0): mflo $10 + mfhi $9 +#else +L(LC0): move $10,$11 + move $9,$12 +#endif + daddu $10,$10,$2 + sltu $2,$10,$2 + sd $10,0($4) + j $31 + daddu $2,$9,$2 # add high product limb and carry from addition + +END (__mpn_mul_1) diff --git a/REORG.TODO/sysdeps/mips/mips64/n32/Implies b/REORG.TODO/sysdeps/mips/mips64/n32/Implies new file mode 100644 index 0000000000..e5d8a0e22f --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/n32/Implies @@ -0,0 +1,5 @@ +mips/ieee754 +ieee754/ldbl-128 +mips/mips64 +mips +wordsize-32 diff --git a/REORG.TODO/sysdeps/mips/mips64/n32/Makefile b/REORG.TODO/sysdeps/mips/mips64/n32/Makefile new file mode 100644 index 0000000000..a84d2a51bd --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/n32/Makefile @@ -0,0 +1,6 @@ +# `long double' is a distinct type we support. +long-double-fcts = yes + +ifeq ($(filter -mabi=n32,$(CC)),) +CC += -mabi=n32 +endif diff --git a/REORG.TODO/sysdeps/mips/mips64/n32/_itoa.h b/REORG.TODO/sysdeps/mips/mips64/n32/_itoa.h new file mode 100644 index 0000000000..363cdfe9ac --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/n32/_itoa.h @@ -0,0 +1,4 @@ +/* MIPS n32 uses 64-bit _itoa_word and _itoa is mapped to _itoa_word. */ +#define _ITOA_NEEDED 0 +#define _ITOA_WORD_TYPE unsigned long long int +#include_next <_itoa.h> diff --git a/REORG.TODO/sysdeps/mips/mips64/n32/crti.S b/REORG.TODO/sysdeps/mips/mips64/n32/crti.S new file mode 100644 index 0000000000..a9e7579e75 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/n32/crti.S @@ -0,0 +1,100 @@ +/* Special .init and .fini section support for MIPS (n32). + Copyright (C) 1995-2017 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.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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/>. */ + +/* crti.S puts a function prologue at the beginning of the .init and + .fini sections and defines global symbols for those addresses, so + they can be called as functions. The symbols _init and _fini are + magic and cause the linker to emit DT_INIT and DT_FINI. */ + +#include <libc-symbols.h> + +#ifdef __mips_micromips +# define JALR_RELOC R_MICROMIPS_JALR +#else +# define JALR_RELOC R_MIPS_JALR +#endif + +#ifndef PREINIT_FUNCTION +# define PREINIT_FUNCTION __gmon_start__ +#endif + +#ifndef PREINIT_FUNCTION_WEAK +# define PREINIT_FUNCTION_WEAK 1 +#endif + +#if PREINIT_FUNCTION_WEAK + weak_extern (PREINIT_FUNCTION) +#else + .hidden PREINIT_FUNCTION +#endif + + .set nomips16 + + .section .init,"ax",@progbits + .p2align 2 + .globl _init + .type _init, @function +_init: + addiu $sp,$sp,-16 + sd $28,0($sp) + lui $28,%hi(%neg(%gp_rel(_init))) + addu $28,$28,$25 + sd $31,8($sp) + addiu $28,$28,%lo(%neg(%gp_rel(_init))) +#if PREINIT_FUNCTION_WEAK + lw $2,%got_disp(PREINIT_FUNCTION)($28) + beq $2,$0,.Lno_weak_fn + lw $25,%call16(PREINIT_FUNCTION)($28) + .reloc 1f,JALR_RELOC,PREINIT_FUNCTION +1: jalr $25 +.Lno_weak_fn: + .insn +#else + lw $25,%got_disp(PREINIT_FUNCTION)($28) + .reloc 1f,JALR_RELOC,PREINIT_FUNCTION +1: jalr $25 +#endif + + .section .fini,"ax",@progbits + .p2align 2 + .globl _fini + .type _fini, @function +_fini: + addiu $sp,$sp,-16 + sd $28,0($sp) + lui $28,%hi(%neg(%gp_rel(_fini))) + addu $28,$28,$25 + sd $31,8($sp) + addiu $28,$28,%lo(%neg(%gp_rel(_fini))) diff --git a/REORG.TODO/sysdeps/mips/mips64/n32/crtn.S b/REORG.TODO/sysdeps/mips/mips64/n32/crtn.S new file mode 100644 index 0000000000..8e0524ac4d --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/n32/crtn.S @@ -0,0 +1,59 @@ +/* Special .init and .fini section support for MIPS (n32). + Copyright (C) 1995-2017 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.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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/>. */ + +/* crtn.S puts function epilogues in the .init and .fini sections + corresponding to the prologues in crti.S. */ + + .set nomips16 + + .section .init,"ax",@progbits + ld $31,8($sp) + ld $28,0($sp) + .set noreorder + .set nomacro + j $31 + addiu $sp,$sp,16 + .set macro + .set reorder + + .section .fini,"ax",@progbits + ld $31,8($sp) + ld $28,0($sp) + .set noreorder + .set nomacro + j $31 + addiu $sp,$sp,16 + .set macro + .set reorder diff --git a/REORG.TODO/sysdeps/mips/mips64/n32/fpu/e_sqrt.c b/REORG.TODO/sysdeps/mips/mips64/n32/fpu/e_sqrt.c new file mode 100644 index 0000000000..81f4e77697 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/n32/fpu/e_sqrt.c @@ -0,0 +1 @@ +#include <sysdeps/mips/fpu/e_sqrt.c> diff --git a/REORG.TODO/sysdeps/mips/mips64/n32/fpu/e_sqrtf.c b/REORG.TODO/sysdeps/mips/mips64/n32/fpu/e_sqrtf.c new file mode 100644 index 0000000000..fb0700d45c --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/n32/fpu/e_sqrtf.c @@ -0,0 +1 @@ +#include <sysdeps/mips/fpu/e_sqrtf.c> diff --git a/REORG.TODO/sysdeps/mips/mips64/n64/Implies b/REORG.TODO/sysdeps/mips/mips64/n64/Implies new file mode 100644 index 0000000000..25ad0cf458 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/n64/Implies @@ -0,0 +1,5 @@ +mips/ieee754 +ieee754/ldbl-128 +mips/mips64 +mips +wordsize-64 diff --git a/REORG.TODO/sysdeps/mips/mips64/n64/Makefile b/REORG.TODO/sysdeps/mips/mips64/n64/Makefile new file mode 100644 index 0000000000..a823f32b53 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/n64/Makefile @@ -0,0 +1,6 @@ +# `long double' is a distinct type we support. +long-double-fcts = yes + +ifeq ($(filter -mabi=64,$(CC)),) +CC += -mabi=64 +endif diff --git a/REORG.TODO/sysdeps/mips/mips64/n64/crti.S b/REORG.TODO/sysdeps/mips/mips64/n64/crti.S new file mode 100644 index 0000000000..b11ea2ccb5 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/n64/crti.S @@ -0,0 +1,100 @@ +/* Special .init and .fini section support for MIPS (n64). + Copyright (C) 1995-2017 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.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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/>. */ + +/* crti.S puts a function prologue at the beginning of the .init and + .fini sections and defines global symbols for those addresses, so + they can be called as functions. The symbols _init and _fini are + magic and cause the linker to emit DT_INIT and DT_FINI. */ + +#include <libc-symbols.h> + +#ifdef __mips_micromips +# define JALR_RELOC R_MICROMIPS_JALR +#else +# define JALR_RELOC R_MIPS_JALR +#endif + +#ifndef PREINIT_FUNCTION +# define PREINIT_FUNCTION __gmon_start__ +#endif + +#ifndef PREINIT_FUNCTION_WEAK +# define PREINIT_FUNCTION_WEAK 1 +#endif + +#if PREINIT_FUNCTION_WEAK + weak_extern (PREINIT_FUNCTION) +#else + .hidden PREINIT_FUNCTION +#endif + + .set nomips16 + + .section .init,"ax",@progbits + .p2align 2 + .globl _init + .type _init, @function +_init: + daddiu $sp,$sp,-16 + sd $28,0($sp) + lui $28,%hi(%neg(%gp_rel(_init))) + daddu $28,$28,$25 + sd $31,8($sp) + daddiu $28,$28,%lo(%neg(%gp_rel(_init))) +#if PREINIT_FUNCTION_WEAK + ld $2,%got_disp(PREINIT_FUNCTION)($28) + beq $2,$0,.Lno_weak_fn + ld $25,%call16(PREINIT_FUNCTION)($28) + .reloc 1f,JALR_RELOC,PREINIT_FUNCTION +1: jalr $25 +.Lno_weak_fn: + .insn +#else + ld $25,%got_disp(PREINIT_FUNCTION)($28) + .reloc 1f,JALR_RELOC,PREINIT_FUNCTION +1: jalr $25 +#endif + + .section .fini,"ax",@progbits + .p2align 2 + .globl _fini + .type _fini, @function +_fini: + daddiu $sp,$sp,-16 + sd $28,0($sp) + lui $28,%hi(%neg(%gp_rel(_fini))) + daddu $28,$28,$25 + sd $31,8($sp) + daddiu $28,$28,%lo(%neg(%gp_rel(_fini))) diff --git a/REORG.TODO/sysdeps/mips/mips64/n64/crtn.S b/REORG.TODO/sysdeps/mips/mips64/n64/crtn.S new file mode 100644 index 0000000000..d3fce8c5c8 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/n64/crtn.S @@ -0,0 +1,59 @@ +/* Special .init and .fini section support for MIPS (n64). + Copyright (C) 1995-2017 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.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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/>. */ + +/* crtn.S puts function epilogues in the .init and .fini sections + corresponding to the prologues in crti.S. */ + + .set nomips16 + + .section .init,"ax",@progbits + ld $31,8($sp) + ld $28,0($sp) + .set noreorder + .set nomacro + j $31 + daddiu $sp,$sp,16 + .set macro + .set reorder + + .section .fini,"ax",@progbits + ld $31,8($sp) + ld $28,0($sp) + .set noreorder + .set nomacro + j $31 + daddiu $sp,$sp,16 + .set macro + .set reorder diff --git a/REORG.TODO/sysdeps/mips/mips64/n64/fpu/e_sqrt.c b/REORG.TODO/sysdeps/mips/mips64/n64/fpu/e_sqrt.c new file mode 100644 index 0000000000..81f4e77697 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/n64/fpu/e_sqrt.c @@ -0,0 +1 @@ +#include <sysdeps/mips/fpu/e_sqrt.c> diff --git a/REORG.TODO/sysdeps/mips/mips64/n64/fpu/e_sqrtf.c b/REORG.TODO/sysdeps/mips/mips64/n64/fpu/e_sqrtf.c new file mode 100644 index 0000000000..fb0700d45c --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/n64/fpu/e_sqrtf.c @@ -0,0 +1 @@ +#include <sysdeps/mips/fpu/e_sqrtf.c> diff --git a/REORG.TODO/sysdeps/mips/mips64/rshift.S b/REORG.TODO/sysdeps/mips/mips64/rshift.S new file mode 100644 index 0000000000..8c13abcadc --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/rshift.S @@ -0,0 +1,97 @@ +/* MIPS3 __mpn_rshift -- + * + * Copyright (C) 1995-2017 Free Software Foundation, Inc. + * + * This file is part of the GNU MP Library. + * + * The GNU MP Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The GNU MP Library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the GNU MP Library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <sysdep.h> +#include <sys/asm.h> + +/* INPUT PARAMETERS + * res_ptr $4 + * src_ptr $5 + * size $6 + * cnt $7 + */ + +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__mpn_rshift) +#ifdef __PIC__ + SETUP_GP /* ??? unused */ +#endif + .set noreorder + .set nomacro + + ld $10,0($5) # load first limb + dsubu $13,$0,$7 + daddiu $6,$6,-1 + and $9,$6,4-1 # number of limbs in first loop + beq $9,$0,L(L0) # if multiple of 4 limbs, skip first loop + dsll $2,$10,$13 # compute function result + + dsubu $6,$6,$9 + +L(Loop0): ld $3,8($5) + daddiu $4,$4,8 + daddiu $5,$5,8 + daddiu $9,$9,-1 + dsrl $11,$10,$7 + dsll $12,$3,$13 + move $10,$3 + or $8,$11,$12 + bne $9,$0,L(Loop0) + sd $8,-8($4) + +L(L0): beq $6,$0,L(Lend) + nop + +L(Loop): ld $3,8($5) + daddiu $4,$4,32 + daddiu $6,$6,-4 + dsrl $11,$10,$7 + dsll $12,$3,$13 + + ld $10,16($5) + dsrl $14,$3,$7 + or $8,$11,$12 + sd $8,-32($4) + dsll $9,$10,$13 + + ld $3,24($5) + dsrl $11,$10,$7 + or $8,$14,$9 + sd $8,-24($4) + dsll $12,$3,$13 + + ld $10,32($5) + dsrl $14,$3,$7 + or $8,$11,$12 + sd $8,-16($4) + dsll $9,$10,$13 + + daddiu $5,$5,32 + or $8,$14,$9 + bgtz $6,L(Loop) + sd $8,-8($4) + +L(Lend): dsrl $8,$10,$7 + j $31 + sd $8,0($4) +END (__mpn_rshift) diff --git a/REORG.TODO/sysdeps/mips/mips64/setjmp.S b/REORG.TODO/sysdeps/mips/mips64/setjmp.S new file mode 100644 index 0000000000..3e4120e1ea --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/setjmp.S @@ -0,0 +1,45 @@ +/* Copyright (C) 1996-2017 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/>. */ + +#include <sgidefs.h> +#include <sysdep.h> +#include <sys/asm.h> + +/* The function __sigsetjmp_aux saves all the registers, but it can't + reliably access the stack or frame pointers, so we pass them in as + extra arguments. */ +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__sigsetjmp) +#ifdef __PIC__ + SETUP_GP +#endif + SETUP_GP64_REG (v0, C_SYMBOL_NAME (__sigsetjmp)) + move a2, sp + move a3, fp + PTR_LA t9, __sigsetjmp_aux +#if _MIPS_SIM == _ABIO32 + nop +#endif + RESTORE_GP64_REG +#if _MIPS_SIM != _ABIO32 + move a4, gp +#endif + jr t9 +END (__sigsetjmp) +hidden_def (__sigsetjmp) diff --git a/REORG.TODO/sysdeps/mips/mips64/setjmp_aux.c b/REORG.TODO/sysdeps/mips/mips64/setjmp_aux.c new file mode 100644 index 0000000000..b43c36a7d5 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/setjmp_aux.c @@ -0,0 +1,76 @@ +/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Brendan Kehoe (brendan@zen.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, see + <http://www.gnu.org/licenses/>. */ + +#include <setjmp.h> +#include <sgidefs.h> + +/* This function is only called via the assembly language routine + __sigsetjmp, which arranges to pass in the stack pointer and the frame + pointer. We do things this way because it's difficult to reliably + access them in C. */ + +int +__sigsetjmp_aux (jmp_buf env, int savemask, long long sp, long long fp, + long long gp) +{ +#ifdef __mips_hard_float + /* Store the floating point callee-saved registers... */ +#if _MIPS_SIM == _ABI64 + asm volatile ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0])); + asm volatile ("s.d $f25, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1])); + asm volatile ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2])); + asm volatile ("s.d $f27, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3])); + asm volatile ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4])); + asm volatile ("s.d $f29, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5])); + asm volatile ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[6])); + asm volatile ("s.d $f31, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[7])); +#else + asm volatile ("s.d $f20, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0])); + asm volatile ("s.d $f22, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1])); + asm volatile ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2])); + asm volatile ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3])); + asm volatile ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4])); + asm volatile ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5])); +#endif +#endif + + /* .. and the PC; */ + asm volatile ("sd $31, %0" : : "m" (env[0].__jmpbuf[0].__pc)); + + /* .. and the stack pointer; */ + env[0].__jmpbuf[0].__sp = sp; + + /* .. and the FP; it'll be in s8. */ + env[0].__jmpbuf[0].__fp = fp; + + /* .. and the GP; */ + env[0].__jmpbuf[0].__gp = gp; + + /* .. and the callee-saved registers; */ + asm volatile ("sd $16, %0" : : "m" (env[0].__jmpbuf[0].__regs[0])); + asm volatile ("sd $17, %0" : : "m" (env[0].__jmpbuf[0].__regs[1])); + asm volatile ("sd $18, %0" : : "m" (env[0].__jmpbuf[0].__regs[2])); + asm volatile ("sd $19, %0" : : "m" (env[0].__jmpbuf[0].__regs[3])); + asm volatile ("sd $20, %0" : : "m" (env[0].__jmpbuf[0].__regs[4])); + asm volatile ("sd $21, %0" : : "m" (env[0].__jmpbuf[0].__regs[5])); + asm volatile ("sd $22, %0" : : "m" (env[0].__jmpbuf[0].__regs[6])); + asm volatile ("sd $23, %0" : : "m" (env[0].__jmpbuf[0].__regs[7])); + + /* Save the signal mask if requested. */ + return __sigjmp_save (env, savemask); +} diff --git a/REORG.TODO/sysdeps/mips/mips64/sfp-machine.h b/REORG.TODO/sysdeps/mips/mips64/sfp-machine.h new file mode 100644 index 0000000000..35cc4ddeb1 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/sfp-machine.h @@ -0,0 +1,108 @@ +#include <fenv.h> +#include <fpu_control.h> + +#define _FP_W_TYPE_SIZE 64 +#define _FP_W_TYPE unsigned long long +#define _FP_WS_TYPE signed long long +#define _FP_I_TYPE long long + +#define _FP_MUL_MEAT_S(R,X,Y) \ + _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y) +#define _FP_MUL_MEAT_D(R,X,Y) \ + _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) +#define _FP_MUL_MEAT_Q(R,X,Y) \ + _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) + +#define _FP_MUL_MEAT_DW_S(R,X,Y) \ + _FP_MUL_MEAT_DW_1_imm(_FP_WFRACBITS_S,R,X,Y) +#define _FP_MUL_MEAT_DW_D(R,X,Y) \ + _FP_MUL_MEAT_DW_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) +#define _FP_MUL_MEAT_DW_Q(R,X,Y) \ + _FP_MUL_MEAT_DW_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) + +#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm) +#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y) +#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y) + +#ifdef __mips_nan2008 +# define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1) +# define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1) +# define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1 +#else +# define _FP_NANFRAC_S (_FP_QNANBIT_S - 1) +# define _FP_NANFRAC_D (_FP_QNANBIT_D - 1) +# define _FP_NANFRAC_Q (_FP_QNANBIT_Q - 1), -1 +#endif +#define _FP_NANSIGN_S 0 +#define _FP_NANSIGN_D 0 +#define _FP_NANSIGN_Q 0 + +#define _FP_KEEPNANFRACP 1 +#ifdef __mips_nan2008 +# define _FP_QNANNEGATEDP 0 +#else +# define _FP_QNANNEGATEDP 1 +#endif + +#ifdef __mips_nan2008 +/* NaN payloads should be preserved for NAN2008. */ +# define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ + do \ + { \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc (R, X); \ + R##_c = FP_CLS_NAN; \ + } \ + while (0) +#else +/* From my experiments it seems X is chosen unless one of the + NaNs is sNaN, in which case the result is NANSIGN/NANFRAC. */ +# define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ + do { \ + if ((_FP_FRAC_HIGH_RAW_##fs(X) | \ + _FP_FRAC_HIGH_RAW_##fs(Y)) & _FP_QNANBIT_##fs) \ + { \ + R##_s = _FP_NANSIGN_##fs; \ + _FP_FRAC_SET_##wc(R,_FP_NANFRAC_##fs); \ + } \ + else \ + { \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc(R,X); \ + } \ + R##_c = FP_CLS_NAN; \ + } while (0) +#endif + +#define _FP_DECL_EX fpu_control_t _fcw + +#define FP_ROUNDMODE (_fcw & 0x3) + +#define FP_RND_NEAREST FE_TONEAREST +#define FP_RND_ZERO FE_TOWARDZERO +#define FP_RND_PINF FE_UPWARD +#define FP_RND_MINF FE_DOWNWARD + +#define FP_EX_INVALID FE_INVALID +#define FP_EX_OVERFLOW FE_OVERFLOW +#define FP_EX_UNDERFLOW FE_UNDERFLOW +#define FP_EX_DIVZERO FE_DIVBYZERO +#define FP_EX_INEXACT FE_INEXACT + +#define _FP_TININESS_AFTER_ROUNDING 1 + +#ifdef __mips_hard_float +#define FP_INIT_ROUNDMODE \ +do { \ + _FPU_GETCW (_fcw); \ +} while (0) + +#define FP_HANDLE_EXCEPTIONS \ +do { \ + if (__builtin_expect (_fex, 0)) \ + _FPU_SETCW (_fcw | _fex | (_fex << 10)); \ +} while (0) +#define FP_TRAPPING_EXCEPTIONS ((_fcw >> 5) & 0x7c) +#else +#define FP_INIT_ROUNDMODE _fcw = FP_RND_NEAREST +#endif diff --git a/REORG.TODO/sysdeps/mips/mips64/sub_n.S b/REORG.TODO/sysdeps/mips/mips64/sub_n.S new file mode 100644 index 0000000000..fe42764724 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/sub_n.S @@ -0,0 +1,125 @@ +/* MIPS3 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and + * store difference in a third limb vector. + * + * Copyright (C) 1995-2017 Free Software Foundation, Inc. + * + * This file is part of the GNU MP Library. + * + * The GNU MP Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The GNU MP Library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the GNU MP Library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <sysdep.h> +#include <sys/asm.h> + +/* INPUT PARAMETERS + * res_ptr $4 + * s1_ptr $5 + * s2_ptr $6 + * size $7 + */ + +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__mpn_sub_n) +#ifdef __PIC__ + SETUP_GP /* ??? unused */ +#endif + .set noreorder + .set nomacro + + ld $10,0($5) + ld $11,0($6) + + daddiu $7,$7,-1 + and $9,$7,4-1 # number of limbs in first loop + beq $9,$0,L(L0) # if multiple of 4 limbs, skip first loop + move $2,$0 + + dsubu $7,$7,$9 + +L(Loop0): daddiu $9,$9,-1 + ld $12,8($5) + daddu $11,$11,$2 + ld $13,8($6) + sltu $8,$11,$2 + dsubu $11,$10,$11 + sltu $2,$10,$11 + sd $11,0($4) + or $2,$2,$8 + + daddiu $5,$5,8 + daddiu $6,$6,8 + move $10,$12 + move $11,$13 + bne $9,$0,L(Loop0) + daddiu $4,$4,8 + +L(L0): beq $7,$0,L(Lend) + nop + +L(Loop): daddiu $7,$7,-4 + + ld $12,8($5) + daddu $11,$11,$2 + ld $13,8($6) + sltu $8,$11,$2 + dsubu $11,$10,$11 + sltu $2,$10,$11 + sd $11,0($4) + or $2,$2,$8 + + ld $10,16($5) + daddu $13,$13,$2 + ld $11,16($6) + sltu $8,$13,$2 + dsubu $13,$12,$13 + sltu $2,$12,$13 + sd $13,8($4) + or $2,$2,$8 + + ld $12,24($5) + daddu $11,$11,$2 + ld $13,24($6) + sltu $8,$11,$2 + dsubu $11,$10,$11 + sltu $2,$10,$11 + sd $11,16($4) + or $2,$2,$8 + + ld $10,32($5) + daddu $13,$13,$2 + ld $11,32($6) + sltu $8,$13,$2 + dsubu $13,$12,$13 + sltu $2,$12,$13 + sd $13,24($4) + or $2,$2,$8 + + daddiu $5,$5,32 + daddiu $6,$6,32 + + bne $7,$0,L(Loop) + daddiu $4,$4,32 + +L(Lend): daddu $11,$11,$2 + sltu $8,$11,$2 + dsubu $11,$10,$11 + sltu $2,$10,$11 + sd $11,0($4) + j $31 + or $2,$2,$8 + +END (__mpn_sub_n) diff --git a/REORG.TODO/sysdeps/mips/mips64/submul_1.S b/REORG.TODO/sysdeps/mips/mips64/submul_1.S new file mode 100644 index 0000000000..11c9851814 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mips64/submul_1.S @@ -0,0 +1,132 @@ +/* MIPS3 __mpn_submul_1 -- Multiply a limb vector with a single limb and + * subtract the product from a second limb vector. + * + * Copyright (C) 1992-2017 Free Software Foundation, Inc. + * + * This file is part of the GNU MP Library. + * + * The GNU MP Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The GNU MP Library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the GNU MP Library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <sysdep.h> +#include <sys/asm.h> + +/* INPUT PARAMETERS + * res_ptr $4 + * s1_ptr $5 + * size $6 + * s2_limb $7 + */ + +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__mpn_submul_1) +#ifdef __PIC__ + SETUP_GP /* ??? unused */ +#endif + .set noreorder + .set nomacro + + # warm up phase 0 + ld $8,0($5) + + # warm up phase 1 + daddiu $5,$5,8 +#if __mips_isa_rev < 6 + dmultu $8,$7 +#else + dmulu $11,$8,$7 + dmuhu $12,$8,$7 +#endif + + daddiu $6,$6,-1 + beq $6,$0,L(LC0) + move $2,$0 # zero cy2 + + daddiu $6,$6,-1 + beq $6,$0,L(LC1) + ld $8,0($5) # load new s1 limb as early as possible + +L(Loop): ld $10,0($4) +#if __mips_isa_rev < 6 + mflo $3 + mfhi $9 +#else + move $3,$11 + move $9,$12 +#endif + daddiu $5,$5,8 + daddu $3,$3,$2 # add old carry limb to low product limb +#if __mips_isa_rev < 6 + dmultu $8,$7 +#else + dmulu $11,$8,$7 + dmuhu $12,$8,$7 +#endif + ld $8,0($5) # load new s1 limb as early as possible + daddiu $6,$6,-1 # decrement loop counter + sltu $2,$3,$2 # carry from previous addition -> $2 + dsubu $3,$10,$3 + sgtu $10,$3,$10 + daddu $2,$2,$10 + sd $3,0($4) + daddiu $4,$4,8 + bne $6,$0,L(Loop) + daddu $2,$9,$2 # add high product limb and carry from addition + + # cool down phase 1 +L(LC1): ld $10,0($4) +#if __mips_isa_rev < 6 + mflo $3 + mfhi $9 +#else + move $3,$11 + move $9,$12 +#endif + daddu $3,$3,$2 + sltu $2,$3,$2 +#if __mips_isa_rev < 6 + dmultu $8,$7 +#else + dmulu $11,$8,$7 + dmuhu $12,$8,$7 +#endif + dsubu $3,$10,$3 + sgtu $10,$3,$10 + daddu $2,$2,$10 + sd $3,0($4) + daddiu $4,$4,8 + daddu $2,$9,$2 # add high product limb and carry from addition + + # cool down phase 0 +L(LC0): ld $10,0($4) +#if __mips_isa_rev < 6 + mflo $3 + mfhi $9 +#else + move $3,$11 + move $9,$12 +#endif + daddu $3,$3,$2 + sltu $2,$3,$2 + dsubu $3,$10,$3 + sgtu $10,$3,$10 + daddu $2,$2,$10 + sd $3,0($4) + j $31 + daddu $2,$9,$2 # add high product limb and carry from addition + +END (__mpn_submul_1) diff --git a/REORG.TODO/sysdeps/mips/mul_1.S b/REORG.TODO/sysdeps/mips/mul_1.S new file mode 100644 index 0000000000..d924f02061 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/mul_1.S @@ -0,0 +1,117 @@ +/* MIPS __mpn_mul_1 -- Multiply a limb vector with a single limb and +store the product in a second limb vector. + +Copyright (C) 1995-2017 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library. If not, see +<http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +/* INPUT PARAMETERS + res_ptr $4 + s1_ptr $5 + size $6 + s2_limb $7 +*/ +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__mpn_mul_1) + .set noreorder +#ifdef __PIC__ + .cpload t9 +#endif + .set nomacro + + /* warm up phase 0 */ + lw $8,0($5) + + /* warm up phase 1 */ + addiu $5,$5,4 +#if __mips_isa_rev < 6 + multu $8,$7 +#else + mulu $11,$8,$7 + muhu $12,$8,$7 +#endif + + addiu $6,$6,-1 + beq $6,$0,L(LC0) + move $2,$0 /* zero cy2 */ + + addiu $6,$6,-1 + beq $6,$0,L(LC1) + lw $8,0($5) /* load new s1 limb as early as possible */ + + +#if __mips_isa_rev < 6 +L(Loop): mflo $10 + mfhi $9 +#else +L(Loop): move $10,$11 + move $9,$12 +#endif + addiu $5,$5,4 + addu $10,$10,$2 /* add old carry limb to low product limb */ +#if __mips_isa_rev < 6 + multu $8,$7 +#else + mulu $11,$8,$7 + muhu $12,$8,$7 +#endif + lw $8,0($5) /* load new s1 limb as early as possible */ + addiu $6,$6,-1 /* decrement loop counter */ + sltu $2,$10,$2 /* carry from previous addition -> $2 */ + sw $10,0($4) + addiu $4,$4,4 + bne $6,$0,L(Loop) /* should be "bnel" */ + addu $2,$9,$2 /* add high product limb and carry from addition */ + + /* cool down phase 1 */ +#if __mips_isa_rev < 6 +L(LC1): mflo $10 + mfhi $9 +#else +L(LC1): move $10,$11 + move $9,$12 +#endif + addu $10,$10,$2 + sltu $2,$10,$2 +#if __mips_isa_rev < 6 + multu $8,$7 +#else + mulu $11,$8,$7 + muhu $12,$8,$7 +#endif + sw $10,0($4) + addiu $4,$4,4 + addu $2,$9,$2 /* add high product limb and carry from addition */ + + /* cool down phase 0 */ +#if __mips_isa_rev < 6 +L(LC0): mflo $10 + mfhi $9 +#else +L(LC0): move $10,$11 + move $9,$12 +#endif + addu $10,$10,$2 + sltu $2,$10,$2 + sw $10,0($4) + j $31 + addu $2,$9,$2 /* add high product limb and carry from addition */ + END (__mpn_mul_1) diff --git a/REORG.TODO/sysdeps/mips/nan-high-order-bit.h b/REORG.TODO/sysdeps/mips/nan-high-order-bit.h new file mode 100644 index 0000000000..bab0cb4e8c --- /dev/null +++ b/REORG.TODO/sysdeps/mips/nan-high-order-bit.h @@ -0,0 +1,32 @@ +/* Specify NaN high-order bit conventions. MIPS version. + Copyright (C) 2016-2017 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 NAN_HIGH_ORDER_BIT_H +#define NAN_HIGH_ORDER_BIT_H 1 + +#ifdef __mips_nan2008 +/* MIPS aligned to IEEE 754-2008. */ +# define HIGH_ORDER_BIT_IS_SET_FOR_SNAN 0 +#else +/* One of the few architectures where the meaning of the + quiet/signaling bit is inverse to IEEE 754-2008 (as well as common + practice for IEEE 754-1985). */ +# define HIGH_ORDER_BIT_IS_SET_FOR_SNAN 1 +#endif + +#endif /* nan-high-order-bit.h */ diff --git a/REORG.TODO/sysdeps/mips/nptl/Makefile b/REORG.TODO/sysdeps/mips/nptl/Makefile new file mode 100644 index 0000000000..f0ca4f3303 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/nptl/Makefile @@ -0,0 +1,25 @@ +# Copyright (C) 2005-2017 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/>. + +ifeq ($(subdir),csu) +gen-as-const-headers += tcb-offsets.sym +endif + +ifeq ($(subdir),nptl) +libpthread-sysdep_routines += nptl-sysdep +libpthread-shared-only-routines += nptl-sysdep +endif diff --git a/REORG.TODO/sysdeps/mips/nptl/bits/pthreadtypes-arch.h b/REORG.TODO/sysdeps/mips/nptl/bits/pthreadtypes-arch.h new file mode 100644 index 0000000000..6aa1bda172 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/nptl/bits/pthreadtypes-arch.h @@ -0,0 +1,87 @@ +/* Machine-specific pthread type layouts. MIPS version. + Copyright (C) 2005-2017 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 _BITS_PTHREADTYPES_ARCH_H +#define _BITS_PTHREADTYPES_ARCH_H 1 + +#include <endian.h> + +#if _MIPS_SIM == _ABI64 +# define __SIZEOF_PTHREAD_ATTR_T 56 +# define __SIZEOF_PTHREAD_MUTEX_T 40 +# define __SIZEOF_PTHREAD_RWLOCK_T 56 +# define __SIZEOF_PTHREAD_BARRIER_T 32 +#else +# define __SIZEOF_PTHREAD_ATTR_T 36 +# define __SIZEOF_PTHREAD_MUTEX_T 24 +# define __SIZEOF_PTHREAD_RWLOCK_T 32 +# define __SIZEOF_PTHREAD_BARRIER_T 20 +#endif +#define __SIZEOF_PTHREAD_MUTEXATTR_T 4 +#define __SIZEOF_PTHREAD_COND_T 48 +#define __SIZEOF_PTHREAD_CONDATTR_T 4 +#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 +#define __SIZEOF_PTHREAD_BARRIERATTR_T 4 + +/* Data structure for mutex handling. */ +#define __PTHREAD_COMPAT_PADDING_MID +#define __PTHREAD_COMPAT_PADDING_END +#define __PTHREAD_MUTEX_LOCK_ELISION 0 + +#define __LOCK_ALIGNMENT +#define __ONCE_ALIGNMENT + +struct __pthread_rwlock_arch_t +{ + unsigned int __readers; + unsigned int __writers; + unsigned int __wrphase_futex; + unsigned int __writers_futex; + unsigned int __pad3; + unsigned int __pad4; +#if _MIPS_SIM == _ABI64 + int __cur_writer; + int __shared; + unsigned long int __pad1; + unsigned long int __pad2; + /* FLAGS must stay at this position in the structure to maintain + binary compatibility. */ + unsigned int __flags; +# else +# if __BYTE_ORDER == __BIG_ENDIAN + unsigned char __pad1; + unsigned char __pad2; + unsigned char __shared; + /* FLAGS must stay at this position in the structure to maintain + binary compatibility. */ + unsigned char __flags; +# else + /* FLAGS must stay at this position in the structure to maintain + binary compatibility. */ + unsigned char __flags; + unsigned char __shared; + unsigned char __pad1; + unsigned char __pad2; +# endif + int __cur_writer; +#endif +}; + +#define __PTHREAD_RWLOCK_ELISION_EXTRA 0 + +#endif /* bits/pthreadtypes.h */ diff --git a/REORG.TODO/sysdeps/mips/nptl/bits/semaphore.h b/REORG.TODO/sysdeps/mips/nptl/bits/semaphore.h new file mode 100644 index 0000000000..64227b92b5 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/nptl/bits/semaphore.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2002-2017 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 _SEMAPHORE_H +# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead." +#endif + +#if _MIPS_SIM == _ABI64 +# define __SIZEOF_SEM_T 32 +#else +# define __SIZEOF_SEM_T 16 +#endif + +/* Value returned if `sem_open' failed. */ +#define SEM_FAILED ((sem_t *) 0) + + +typedef union +{ + char __size[__SIZEOF_SEM_T]; + long int __align; +} sem_t; diff --git a/REORG.TODO/sysdeps/mips/nptl/nptl-sysdep.S b/REORG.TODO/sysdeps/mips/nptl/nptl-sysdep.S new file mode 100644 index 0000000000..3f5c2a364a --- /dev/null +++ b/REORG.TODO/sysdeps/mips/nptl/nptl-sysdep.S @@ -0,0 +1,2 @@ +/* Pull in __syscall_error. */ +#include <sysdep.S> diff --git a/REORG.TODO/sysdeps/mips/nptl/pthreaddef.h b/REORG.TODO/sysdeps/mips/nptl/pthreaddef.h new file mode 100644 index 0000000000..1adfe668b6 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/nptl/pthreaddef.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2002-2017 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/>. */ + +/* Default stack size. */ +#define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024) + +/* Required stack pointer alignment at beginning. */ +#define STACK_ALIGN 16 + +/* Minimal stack size after allocating thread descriptor and guard size. */ +#define MINIMAL_REST_STACK 2048 + +/* Alignment requirement for TCB. */ +#define TCB_ALIGNMENT 16 + + +/* Location of current stack frame. */ +#define CURRENT_STACK_FRAME __builtin_frame_address (0) diff --git a/REORG.TODO/sysdeps/mips/nptl/tcb-offsets.sym b/REORG.TODO/sysdeps/mips/nptl/tcb-offsets.sym new file mode 100644 index 0000000000..9ea25b94a8 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/nptl/tcb-offsets.sym @@ -0,0 +1,10 @@ +#include <sysdep.h> +#include <tls.h> + +-- + +-- Abuse tls.h macros to derive offsets relative to the thread register. +#define thread_offsetof(mem) (long)(offsetof(struct pthread, mem) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) + +MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) +TID_OFFSET thread_offsetof (tid) diff --git a/REORG.TODO/sysdeps/mips/nptl/tls.h b/REORG.TODO/sysdeps/mips/nptl/tls.h new file mode 100644 index 0000000000..913f7d33f9 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/nptl/tls.h @@ -0,0 +1,186 @@ +/* Definition for thread-local data handling. NPTL/MIPS version. + Copyright (C) 2005-2017 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 _TLS_H +#define _TLS_H 1 + +#include <dl-sysdep.h> + +#ifndef __ASSEMBLER__ +# include <stdbool.h> +# include <stddef.h> +# include <stdint.h> +# include <dl-dtv.h> + +/* Get system call information. */ +# include <sysdep.h> + +#ifdef __mips16 +/* MIPS16 uses GCC builtin to access the TP. */ +# define READ_THREAD_POINTER() (__builtin_thread_pointer ()) +#else +/* Note: rd must be $v1 to be ABI-conformant. */ +# if __mips_isa_rev >= 2 +# define READ_THREAD_POINTER() \ + ({ void *__result; \ + asm volatile ("rdhwr\t%0, $29" : "=v" (__result)); \ + __result; }) +# else +# define READ_THREAD_POINTER() \ + ({ void *__result; \ + asm volatile (".set\tpush\n\t.set\tmips32r2\n\t" \ + "rdhwr\t%0, $29\n\t.set\tpop" : "=v" (__result)); \ + __result; }) +# endif +#endif + +#else /* __ASSEMBLER__ */ +# include <tcb-offsets.h> + +# if __mips_isa_rev >= 2 +# define READ_THREAD_POINTER(rd) rdhwr rd, $29 +# else +# define READ_THREAD_POINTER(rd) \ + .set push; \ + .set mips32r2; \ + rdhwr rd, $29; \ + .set pop +# endif +#endif /* __ASSEMBLER__ */ + + +#ifndef __ASSEMBLER__ + +/* The TP points to the start of the thread blocks. */ +# define TLS_DTV_AT_TP 1 +# define TLS_TCB_AT_TP 0 + +/* Get the thread descriptor definition. */ +# include <nptl/descr.h> + +typedef struct +{ + dtv_t *dtv; + void *private; +} tcbhead_t; + +/* This is the size of the initial TCB. Because our TCB is before the thread + pointer, we don't need this. */ +# define TLS_INIT_TCB_SIZE 0 + +/* Alignment requirements for the initial TCB. */ +# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) + +/* This is the size of the TCB. Because our TCB is before the thread + pointer, we don't need this. */ +# define TLS_TCB_SIZE 0 + +/* Alignment requirements for the TCB. */ +# define TLS_TCB_ALIGN __alignof__ (struct pthread) + +/* This is the size we need before TCB - actually, it includes the TCB. */ +# define TLS_PRE_TCB_SIZE \ + (sizeof (struct pthread) \ + + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1))) + +/* The thread pointer (in hardware register $29) points to the end of + the TCB + 0x7000, as for PowerPC. The pthread_descr structure is + immediately in front of the TCB. */ +# define TLS_TCB_OFFSET 0x7000 + +/* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ +# define INSTALL_DTV(tcbp, dtvp) \ + (((tcbhead_t *) (tcbp))[-1].dtv = (dtvp) + 1) + +/* Install new dtv for current thread. */ +# define INSTALL_NEW_DTV(dtv) \ + (THREAD_DTV() = (dtv)) + +/* Return dtv of given thread descriptor. */ +# define GET_DTV(tcbp) \ + (((tcbhead_t *) (tcbp))[-1].dtv) + +/* Code to initially initialize the thread pointer. This might need + special attention since 'errno' is not yet available and if the + operation can cause a failure 'errno' must not be touched. */ +# define TLS_INIT_TP(tcbp) \ + ({ INTERNAL_SYSCALL_DECL (err); \ + long result_var; \ + result_var = INTERNAL_SYSCALL (set_thread_area, err, 1, \ + (char *) (tcbp) + TLS_TCB_OFFSET); \ + INTERNAL_SYSCALL_ERROR_P (result_var, err) \ + ? "unknown error" : NULL; }) + +/* Value passed to 'clone' for initialization of the thread register. */ +# define TLS_DEFINE_INIT_TP(tp, pd) \ + void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE + +/* Return the address of the dtv for the current thread. */ +# define THREAD_DTV() \ + (((tcbhead_t *) (READ_THREAD_POINTER () - TLS_TCB_OFFSET))[-1].dtv) + +/* Return the thread descriptor for the current thread. */ +# define THREAD_SELF \ + ((struct pthread *) (READ_THREAD_POINTER () \ + - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)) + +/* Magic for libthread_db to know how to do THREAD_SELF. */ +# define DB_THREAD_SELF \ + CONST_THREAD_AREA (32, TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE) + +/* Access to data in the thread descriptor is easy. */ +# define THREAD_GETMEM(descr, member) \ + descr->member +# define THREAD_GETMEM_NC(descr, member, idx) \ + descr->member[idx] +# define THREAD_SETMEM(descr, member, value) \ + descr->member = (value) +# define THREAD_SETMEM_NC(descr, member, idx, value) \ + descr->member[idx] = (value) + +/* l_tls_offset == 0 is perfectly valid on MIPS, so we have to use some + different value to mean unset l_tls_offset. */ +# define NO_TLS_OFFSET -1 + +/* Get and set the global scope generation counter in struct pthread. */ +#define THREAD_GSCOPE_FLAG_UNUSED 0 +#define THREAD_GSCOPE_FLAG_USED 1 +#define THREAD_GSCOPE_FLAG_WAIT 2 +#define THREAD_GSCOPE_RESET_FLAG() \ + do \ + { int __res \ + = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ + THREAD_GSCOPE_FLAG_UNUSED); \ + if (__res == THREAD_GSCOPE_FLAG_WAIT) \ + lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \ + } \ + while (0) +#define THREAD_GSCOPE_SET_FLAG() \ + do \ + { \ + THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ + atomic_write_barrier (); \ + } \ + while (0) +#define THREAD_GSCOPE_WAIT() \ + GL(dl_wait_lookup_done) () + +#endif /* __ASSEMBLER__ */ + +#endif /* tls.h */ diff --git a/REORG.TODO/sysdeps/mips/preconfigure b/REORG.TODO/sysdeps/mips/preconfigure new file mode 100644 index 0000000000..c118592b27 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/preconfigure @@ -0,0 +1,29 @@ +case "$machine" in +mips*) + abiflag=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | sed -n 's/^#define _MIPS_SIM \(.*\)/\1/p'` + mips16flag=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null | sed -n 's/^#define __mips16 \(.*\)/\1/p'` + + base_machine=mips + if test "$abiflag" = "_ABIO32" ; then + if test "$mips16flag" = "1" ; then + machine=mips/mips32/mips16 + else + machine=mips/mips32 + fi + elif test "$abiflag" = "_ABIN32" ; then + machine=mips/mips64/n32 + elif test "$abiflag" = "_ABI64" ; then + machine=mips/mips64/n64 + else + as_fn_error $? "Unable to determine ABI." "$LINENO" 5 + fi + # $config_machine is not really needed here but the slash after + # $machine is needed by the case statement in + # sysdeps/unix/sysv/linux/mips/configure.ac. + machine=$machine/$config_machine + + if test "$abiflag" != "_ABIO32" -a "$mips16flag" = "1"; then + as_fn_error $? "MIPS16 is only supported with the o32 ABI." "$LINENO" 5 + fi + ;; +esac diff --git a/REORG.TODO/sysdeps/mips/regdef.h b/REORG.TODO/sysdeps/mips/regdef.h new file mode 100644 index 0000000000..9674826311 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/regdef.h @@ -0,0 +1,25 @@ +/* Copyright (C) 1994-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ralf Baechle <ralf@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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _REGDEF_H +#define _REGDEF_H + +#include <sys/regdef.h> +#include <sys/fpregdef.h> + +#endif /* _REGDEF_H */ diff --git a/REORG.TODO/sysdeps/mips/rshift.S b/REORG.TODO/sysdeps/mips/rshift.S new file mode 100644 index 0000000000..4850d8c5b2 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/rshift.S @@ -0,0 +1,94 @@ +/* MIPS2 __mpn_rshift -- + +Copyright (C) 1995-2017 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library. If not, see +<http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +/* INPUT PARAMETERS + res_ptr $4 + src_ptr $5 + size $6 + cnt $7 +*/ +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__mpn_rshift) + .set noreorder +#ifdef __PIC__ + .cpload t9 +#endif + .set nomacro + + lw $10,0($5) /* load first limb */ + subu $13,$0,$7 + addiu $6,$6,-1 + and $9,$6,4-1 /* number of limbs in first loop */ + beq $9,$0,L(L0) /* if multiple of 4 limbs, skip first loop*/ + sll $2,$10,$13 /* compute function result */ + + subu $6,$6,$9 + +L(Loop0): lw $3,4($5) + addiu $4,$4,4 + addiu $5,$5,4 + addiu $9,$9,-1 + srl $11,$10,$7 + sll $12,$3,$13 + move $10,$3 + or $8,$11,$12 + bne $9,$0,L(Loop0) + sw $8,-4($4) + +L(L0): beq $6,$0,L(Lend) + nop + +L(Loop): lw $3,4($5) + addiu $4,$4,16 + addiu $6,$6,-4 + srl $11,$10,$7 + sll $12,$3,$13 + + lw $10,8($5) + srl $14,$3,$7 + or $8,$11,$12 + sw $8,-16($4) + sll $9,$10,$13 + + lw $3,12($5) + srl $11,$10,$7 + or $8,$14,$9 + sw $8,-12($4) + sll $12,$3,$13 + + lw $10,16($5) + srl $14,$3,$7 + or $8,$11,$12 + sw $8,-8($4) + sll $9,$10,$13 + + addiu $5,$5,16 + or $8,$14,$9 + bgtz $6,L(Loop) + sw $8,-4($4) + +L(Lend): srl $8,$10,$7 + j $31 + sw $8,0($4) + END (__mpn_rshift) diff --git a/REORG.TODO/sysdeps/mips/setjmp.S b/REORG.TODO/sysdeps/mips/setjmp.S new file mode 100644 index 0000000000..2a5633b43b --- /dev/null +++ b/REORG.TODO/sysdeps/mips/setjmp.S @@ -0,0 +1,47 @@ +/* Copyright (C) 1996-2017 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/>. */ + +#include <sysdep.h> + + .set nomips16 + +/* The function __sigsetjmp_aux saves all the registers, but it can't + reliably access the stack or frame pointers, so we pass them in as + extra arguments. */ +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__sigsetjmp) +#ifdef __PIC__ + .set noreorder + .cpload t9 + .set reorder +#endif + move a2, sp +#ifdef fp + move a3, fp +#else + move a3, $fp +#endif +#ifdef __PIC__ + la t9, __sigsetjmp_aux + jr t9 +#else + j __sigsetjmp_aux +#endif +END (__sigsetjmp) +hidden_def (__sigsetjmp) diff --git a/REORG.TODO/sysdeps/mips/setjmp_aux.c b/REORG.TODO/sysdeps/mips/setjmp_aux.c new file mode 100644 index 0000000000..0052e0c4a4 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/setjmp_aux.c @@ -0,0 +1,63 @@ +/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Brendan Kehoe (brendan@zen.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, see + <http://www.gnu.org/licenses/>. */ + +#include <setjmp.h> + +/* This function is only called via the assembly language routine + __sigsetjmp, which arranges to pass in the stack pointer and the frame + pointer. We do things this way because it's difficult to reliably + access them in C. */ + +int __attribute__ ((nomips16)) +__sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp) +{ +#ifdef __mips_hard_float + /* Store the floating point callee-saved registers... */ + asm volatile ("s.d $f20, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0])); + asm volatile ("s.d $f22, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1])); + asm volatile ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2])); + asm volatile ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3])); + asm volatile ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4])); + asm volatile ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5])); +#endif + + /* .. and the PC; */ + asm volatile ("sw $31, %0" : : "m" (env[0].__jmpbuf[0].__pc)); + + /* .. and the stack pointer; */ + env[0].__jmpbuf[0].__sp = (void *) sp; + + /* .. and the FP; it'll be in s8. */ + env[0].__jmpbuf[0].__fp = (void *) fp; + + /* .. and the GP; */ + asm volatile ("sw $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp)); + + /* .. and the callee-saved registers; */ + asm volatile ("sw $16, %0" : : "m" (env[0].__jmpbuf[0].__regs[0])); + asm volatile ("sw $17, %0" : : "m" (env[0].__jmpbuf[0].__regs[1])); + asm volatile ("sw $18, %0" : : "m" (env[0].__jmpbuf[0].__regs[2])); + asm volatile ("sw $19, %0" : : "m" (env[0].__jmpbuf[0].__regs[3])); + asm volatile ("sw $20, %0" : : "m" (env[0].__jmpbuf[0].__regs[4])); + asm volatile ("sw $21, %0" : : "m" (env[0].__jmpbuf[0].__regs[5])); + asm volatile ("sw $22, %0" : : "m" (env[0].__jmpbuf[0].__regs[6])); + asm volatile ("sw $23, %0" : : "m" (env[0].__jmpbuf[0].__regs[7])); + + /* Save the signal mask if requested. */ + return __sigjmp_save (env, savemask); +} diff --git a/REORG.TODO/sysdeps/mips/sgidefs.h b/REORG.TODO/sysdeps/mips/sgidefs.h new file mode 100644 index 0000000000..e43ba15775 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/sgidefs.h @@ -0,0 +1,76 @@ +/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ralf Baechle <ralf@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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SGIDEFS_H +#define _SGIDEFS_H 1 + +/* + * A crude hack to stop <asm/sgidefs.h> + */ +#undef __ASM_SGIDEFS_H +#define __ASM_SGIDEFS_H + +/* + * And remove any damage it might have already done + */ +#undef _MIPS_ISA_MIPS1 +#undef _MIPS_ISA_MIPS2 +#undef _MIPS_ISA_MIPS3 +#undef _MIPS_ISA_MIPS4 +#undef _MIPS_ISA_MIPS5 +#undef _MIPS_ISA_MIPS32 +#undef _MIPS_ISA_MIPS64 + +#undef _MIPS_SIM_ABI32 +#undef _MIPS_SIM_NABI32 +#undef _MIPS_SIM_ABI64 + +/* + * Definitions for the ISA level + */ +#define _MIPS_ISA_MIPS1 1 +#define _MIPS_ISA_MIPS2 2 +#define _MIPS_ISA_MIPS3 3 +#define _MIPS_ISA_MIPS4 4 +#define _MIPS_ISA_MIPS5 5 +#define _MIPS_ISA_MIPS32 6 +#define _MIPS_ISA_MIPS64 7 + +/* + * Subprogram calling convention + */ +#ifndef _ABIO32 +# define _ABIO32 1 +#endif +#define _MIPS_SIM_ABI32 _ABIO32 + +#ifndef _ABIN32 +# define _ABIN32 2 +#endif +#define _MIPS_SIM_NABI32 _ABIN32 + +#ifndef _ABI64 +# define _ABI64 3 +#endif +#define _MIPS_SIM_ABI64 _ABI64 + +#ifndef _ABIO64 +# define _ABIO64 4 +#endif + +#endif /* sgidefs.h */ diff --git a/REORG.TODO/sysdeps/mips/sotruss-lib.c b/REORG.TODO/sysdeps/mips/sotruss-lib.c new file mode 100644 index 0000000000..65df0de989 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/sotruss-lib.c @@ -0,0 +1,117 @@ +/* Override generic sotruss-lib.c to define actual functions for MIPS. + Copyright (C) 2012-2017 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/>. */ + +#define HAVE_ARCH_PLTENTER +#define HAVE_ARCH_PLTEXIT + +#include <elf/sotruss-lib.c> + +#if _MIPS_SIM == _ABIO32 + +ElfW(Addr) +la_mips_o32_gnu_pltenter (ElfW(Sym) *sym __attribute__ ((unused)), + unsigned int ndx __attribute__ ((unused)), + uintptr_t *refcook, uintptr_t *defcook, + La_mips_32_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + print_enter (refcook, defcook, symname, + regs->lr_reg[0], regs->lr_reg[1], regs->lr_reg[2], + *flags); + + /* No need to copy anything, we will not need the parameters in any case. */ + *framesizep = 0; + + return sym->st_value; +} + +unsigned int +la_mips_o32_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, + const struct La_mips_32_regs *inregs, + struct La_mips_32_retval *outregs, + const char *symname) +{ + print_exit (refcook, defcook, symname, outregs->lrv_v0); + + return 0; +} + +#elif _MIPS_SIM == _ABIN32 + +ElfW(Addr) +la_mips_n32_gnu_pltenter (ElfW(Sym) *sym __attribute__ ((unused)), + unsigned int ndx __attribute__ ((unused)), + uintptr_t *refcook, uintptr_t *defcook, + La_mips_64_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + print_enter (refcook, defcook, symname, + regs->lr_reg[0], regs->lr_reg[1], regs->lr_reg[2], + *flags); + + /* No need to copy anything, we will not need the parameters in any case. */ + *framesizep = 0; + + return sym->st_value; +} + +unsigned int +la_mips_n32_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, + const struct La_mips_64_regs *inregs, + struct La_mips_64_retval *outregs, + const char *symname) +{ + print_exit (refcook, defcook, symname, outregs->lrv_v0); + + return 0; +} + +#else + +ElfW(Addr) +la_mips_n64_gnu_pltenter (ElfW(Sym) *sym __attribute__ ((unused)), + unsigned int ndx __attribute__ ((unused)), + uintptr_t *refcook, uintptr_t *defcook, + La_mips_64_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + print_enter (refcook, defcook, symname, + regs->lr_reg[0], regs->lr_reg[1], regs->lr_reg[2], + *flags); + + /* No need to copy anything, we will not need the parameters in any case. */ + *framesizep = 0; + + return sym->st_value; +} + +unsigned int +la_mips_n64_gnu_pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, + const struct La_mips_64_regs *inregs, + struct La_mips_64_retval *outregs, + const char *symname) +{ + print_exit (refcook, defcook, symname, outregs->lrv_v0); + + return 0; +} + +#endif diff --git a/REORG.TODO/sysdeps/mips/stackinfo.h b/REORG.TODO/sysdeps/mips/stackinfo.h new file mode 100644 index 0000000000..67a532ca92 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/stackinfo.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2000-2017 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/>. */ + +/* This file contains a bit of information about the stack allocation + of the processor. */ + +#ifndef _STACKINFO_H +#define _STACKINFO_H 1 + +#include <elf.h> + +/* On MIPS the stack grows down. */ +#define _STACK_GROWS_DOWN 1 + +/* Default to an executable stack. PF_X can be overridden if PT_GNU_STACK is + * present, but it is presumed absent. */ +#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X) + +#endif /* stackinfo.h */ diff --git a/REORG.TODO/sysdeps/mips/start.S b/REORG.TODO/sysdeps/mips/start.S new file mode 100644 index 0000000000..777b42d4ce --- /dev/null +++ b/REORG.TODO/sysdeps/mips/start.S @@ -0,0 +1,185 @@ +/* Startup code compliant to the ELF Mips ABI. + Copyright (C) 1995-2017 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.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 __ASSEMBLY__ 1 +#include <entry.h> +#include <sgidefs.h> +#include <sys/asm.h> + +#ifndef ENTRY_POINT +#error ENTRY_POINT needs to be defined for start.S on MIPS/ELF. +#endif + +/* This is the canonical entry point, usually the first thing in the text + segment. The SVR4/Mips ABI (pages 3-31, 3-32) says that when the entry + point runs, most registers' values are unspecified, except for: + + v0 ($2) 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. + + sp ($29) The stack contains the arguments and environment: + 0(%esp) argc + 4(%esp) argv[0] + ... + (4*argc)(%esp) NULL + (4*(argc+1))(%esp) envp[0] + ... + NULL + ra ($31) The return address register is set to zero so that programs + that search backword through stack frames recognize the last + stack frame. +*/ + + +/* We need to call: + __libc_start_main (int (*main) (int, char **, char **), int argc, + char **argv, void (*init) (void), void (*fini) (void), + void (*rtld_fini) (void), void *stack_end) +*/ + + .text + .globl ENTRY_POINT + .type ENTRY_POINT,@function +#ifndef __mips16 +ENTRY_POINT: +# ifdef __PIC__ + SETUP_GPX($0) + SETUP_GPX64($25,$0) +# else + PTR_LA $28, _gp /* Setup GP correctly if we're non-PIC. */ + move $31, $0 +# endif + + PTR_LA $4, main /* main */ + PTR_L $5, 0($29) /* argc */ + PTR_ADDIU $6, $29, PTRSIZE /* argv */ + + /* Allocate space on the stack for seven arguments (o32 only) + and make sure the stack is aligned to double words (8 bytes) + on o32 and quad words (16 bytes) on n32 and n64. */ + + and $29, -2 * SZREG +# if _MIPS_SIM == _ABIO32 + PTR_SUBIU $29, 32 +# endif + PTR_LA $7, __libc_csu_init /* init */ + PTR_LA $8, __libc_csu_fini +# if _MIPS_SIM == _ABIO32 + PTR_S $8, 16($29) /* fini */ + PTR_S $2, 20($29) /* rtld_fini */ + PTR_S $29, 24($29) /* stack_end */ +# else + move $9, $2 /* rtld_fini */ + move $10, $29 /* stack_end */ +# endif + PTR_LA $25, __libc_start_main + jalr $25 +hlt: b hlt /* Crash if somehow it does return. */ + +#elif _MIPS_SIM == _ABIO32 /* __mips16 */ + /* MIPS16 entry point. */ + .set mips16 +ENTRY_POINT: +# ifdef __PIC__ + li $3, %hi(_gp_disp) + addiu $4, $pc, %lo(_gp_disp) + sll $3, 16 + addu $3, $4 + move $gp, $3 +# else + li $3, %hi(_gp) + sll $3, 16 + addiu $3, %lo(_gp) + move $gp, $3 +# endif + /* Tie end of stack frames. */ + li $4, 0 + move $31, $4 + /* Create new SP value in $7, including alignment. */ + li $4, 2 * SZREG + neg $4, $4 + move $7, $sp + and $7, $4 + addiu $7, -32 + /* Load arguments with original SP. */ + lw $5, 0($sp) + addiu $6, $sp, PTRSIZE + /* Update SP. */ + move $sp, $7 + /* Lay out last arguments, and call __libc_start_main(). */ +# ifdef __PIC__ + sw $7, 24($sp) /* stack_end */ + lw $4, %got(__libc_csu_fini)($3) + lw $7, %got(__libc_csu_init)($3) /* init */ + sw $4, 16($sp) /* fini */ + lw $4, %got(main)($3) /* main */ + lw $3, %call16(__libc_start_main)($3) + sw $2, 20($sp) /* rtld_fini */ + move $25, $3 + jalr $3 +# else + lw $4, 1f + sw $7, 24($sp) /* stack_end */ + lw $7, 2f /* init */ + sw $4, 16($sp) /* fini */ + lw $4, 3f /* main */ + sw $2, 20($sp) /* rtld_fini */ + /* Load and call __libc_start_main(). */ + lw $3, 4f + jalr $3 +# endif +hlt: b hlt /* Crash if somehow it does return. */ +# ifndef __PIC__ + .align 2 +1: .word __libc_csu_fini +2: .word __libc_csu_init +3: .word main +4: .word __libc_start_main +# endif + +#else /* __mips16 && _MIPS_SIM != _ABIO32 */ +# error "MIPS16 support for N32/N64 not implemented" + +#endif /* __mips16 */ + +/* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start +__data_start: + .long 0 + .weak data_start + data_start = __data_start diff --git a/REORG.TODO/sysdeps/mips/strcmp.S b/REORG.TODO/sysdeps/mips/strcmp.S new file mode 100644 index 0000000000..61e52b8c73 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/strcmp.S @@ -0,0 +1,249 @@ +/* Copyright (C) 2014-2017 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/>. */ + +#ifdef ANDROID_CHANGES +# include "machine/asm.h" +# include "machine/regdef.h" +#elif _LIBC +# include <sysdep.h> +# include <regdef.h> +# include <sys/asm.h> +#elif defined _COMPILING_NEWLIB +# include "machine/asm.h" +# include "machine/regdef.h" +#else +# include <regdef.h> +# include <sys/asm.h> +#endif + +/* Technically strcmp should not read past the end of the strings being + compared. We will read a full word that may contain excess bits beyond + the NULL string terminator but unless ENABLE_READAHEAD is set, we will not + read the next word after the end of string. Setting ENABLE_READAHEAD will + improve performance but is technically illegal based on the definition of + strcmp. */ +#ifdef ENABLE_READAHEAD +# define DELAY_READ +#else +# define DELAY_READ nop +#endif + +/* Testing on a little endian machine showed using CLZ was a + performance loss, so we are not turning it on by default. */ +#if defined(ENABLE_CLZ) && (__mips_isa_rev > 1) +# define USE_CLZ +#endif + +/* Some asm.h files do not have the L macro definition. */ +#ifndef L +# if _MIPS_SIM == _ABIO32 +# define L(label) $L ## label +# else +# define L(label) .L ## label +# endif +#endif + +/* Some asm.h files do not have the PTR_ADDIU macro definition. */ +#ifndef PTR_ADDIU +# ifdef USE_DOUBLE +# define PTR_ADDIU daddiu +# else +# define PTR_ADDIU addiu +# endif +#endif + +/* Allow the routine to be named something else if desired. */ +#ifndef STRCMP_NAME +# define STRCMP_NAME strcmp +#endif + +#ifdef ANDROID_CHANGES +LEAF(STRCMP_NAME, 0) +#else +LEAF(STRCMP_NAME) +#endif + .set nomips16 + .set noreorder + + or t0, a0, a1 + andi t0,0x3 + bne t0, zero, L(byteloop) + +/* Both strings are 4 byte aligned at this point. */ + + lui t8, 0x0101 + ori t8, t8, 0x0101 + lui t9, 0x7f7f + ori t9, 0x7f7f + +#define STRCMP32(OFFSET) \ + lw v0, OFFSET(a0); \ + lw v1, OFFSET(a1); \ + subu t0, v0, t8; \ + bne v0, v1, L(worddiff); \ + nor t1, v0, t9; \ + and t0, t0, t1; \ + bne t0, zero, L(returnzero) + +L(wordloop): + STRCMP32(0) + DELAY_READ + STRCMP32(4) + DELAY_READ + STRCMP32(8) + DELAY_READ + STRCMP32(12) + DELAY_READ + STRCMP32(16) + DELAY_READ + STRCMP32(20) + DELAY_READ + STRCMP32(24) + DELAY_READ + STRCMP32(28) + PTR_ADDIU a0, a0, 32 + b L(wordloop) + PTR_ADDIU a1, a1, 32 + +L(returnzero): + j ra + move v0, zero + +L(worddiff): +#ifdef USE_CLZ + subu t0, v0, t8 + nor t1, v0, t9 + and t1, t0, t1 + xor t0, v0, v1 + or t0, t0, t1 +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + wsbh t0, t0 + rotr t0, t0, 16 +# endif + clz t1, t0 + and t1, 0xf8 +# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + neg t1 + addu t1, 24 +# endif + rotrv v0, v0, t1 + rotrv v1, v1, t1 + and v0, v0, 0xff + and v1, v1, 0xff + j ra + subu v0, v0, v1 +#else /* USE_CLZ */ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + andi t0, v0, 0xff + beq t0, zero, L(wexit01) + andi t1, v1, 0xff + bne t0, t1, L(wexit01) + + srl t8, v0, 8 + srl t9, v1, 8 + andi t8, t8, 0xff + beq t8, zero, L(wexit89) + andi t9, t9, 0xff + bne t8, t9, L(wexit89) + + srl t0, v0, 16 + srl t1, v1, 16 + andi t0, t0, 0xff + beq t0, zero, L(wexit01) + andi t1, t1, 0xff + bne t0, t1, L(wexit01) + + srl t8, v0, 24 + srl t9, v1, 24 +# else /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */ + srl t0, v0, 24 + beq t0, zero, L(wexit01) + srl t1, v1, 24 + bne t0, t1, L(wexit01) + + srl t8, v0, 16 + srl t9, v1, 16 + andi t8, t8, 0xff + beq t8, zero, L(wexit89) + andi t9, t9, 0xff + bne t8, t9, L(wexit89) + + srl t0, v0, 8 + srl t1, v1, 8 + andi t0, t0, 0xff + beq t0, zero, L(wexit01) + andi t1, t1, 0xff + bne t0, t1, L(wexit01) + + andi t8, v0, 0xff + andi t9, v1, 0xff +# endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */ + +L(wexit89): + j ra + subu v0, t8, t9 +L(wexit01): + j ra + subu v0, t0, t1 +#endif /* USE_CLZ */ + +/* It might seem better to do the 'beq' instruction between the two 'lbu' + instructions so that the nop is not needed but testing showed that this + code is actually faster (based on glibc strcmp test). */ +#define BYTECMP01(OFFSET) \ + lbu v0, OFFSET(a0); \ + lbu v1, OFFSET(a1); \ + beq v0, zero, L(bexit01); \ + nop; \ + bne v0, v1, L(bexit01) + +#define BYTECMP89(OFFSET) \ + lbu t8, OFFSET(a0); \ + lbu t9, OFFSET(a1); \ + beq t8, zero, L(bexit89); \ + nop; \ + bne t8, t9, L(bexit89) + +L(byteloop): + BYTECMP01(0) + BYTECMP89(1) + BYTECMP01(2) + BYTECMP89(3) + BYTECMP01(4) + BYTECMP89(5) + BYTECMP01(6) + BYTECMP89(7) + PTR_ADDIU a0, a0, 8 + b L(byteloop) + PTR_ADDIU a1, a1, 8 + +L(bexit01): + j ra + subu v0, v0, v1 +L(bexit89): + j ra + subu v0, t8, t9 + + .set at + .set reorder + +END(STRCMP_NAME) +#ifndef ANDROID_CHANGES +# ifdef _LIBC +libc_hidden_builtin_def (STRCMP_NAME) +# endif +#endif diff --git a/REORG.TODO/sysdeps/mips/sub_n.S b/REORG.TODO/sysdeps/mips/sub_n.S new file mode 100644 index 0000000000..3996dcd8eb --- /dev/null +++ b/REORG.TODO/sysdeps/mips/sub_n.S @@ -0,0 +1,121 @@ +/* MIPS2 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and +store difference in a third limb vector. + +Copyright (C) 1995-2017 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library. If not, see +<http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +/* INPUT PARAMETERS + res_ptr $4 + s1_ptr $5 + s2_ptr $6 + size $7 +*/ +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__mpn_sub_n) + .set noreorder +#ifdef __PIC__ + .cpload t9 +#endif + .set nomacro + + lw $10,0($5) + lw $11,0($6) + + addiu $7,$7,-1 + and $9,$7,4-1 /* number of limbs in first loop */ + beq $9,$0,L(L0) /* if multiple of 4 limbs, skip first loop */ + move $2,$0 + + subu $7,$7,$9 + +L(Loop0): addiu $9,$9,-1 + lw $12,4($5) + addu $11,$11,$2 + lw $13,4($6) + sltu $8,$11,$2 + subu $11,$10,$11 + sltu $2,$10,$11 + sw $11,0($4) + or $2,$2,$8 + + addiu $5,$5,4 + addiu $6,$6,4 + move $10,$12 + move $11,$13 + bne $9,$0,L(Loop0) + addiu $4,$4,4 + +L(L0): beq $7,$0,L(Lend) + nop + +L(Loop): addiu $7,$7,-4 + + lw $12,4($5) + addu $11,$11,$2 + lw $13,4($6) + sltu $8,$11,$2 + subu $11,$10,$11 + sltu $2,$10,$11 + sw $11,0($4) + or $2,$2,$8 + + lw $10,8($5) + addu $13,$13,$2 + lw $11,8($6) + sltu $8,$13,$2 + subu $13,$12,$13 + sltu $2,$12,$13 + sw $13,4($4) + or $2,$2,$8 + + lw $12,12($5) + addu $11,$11,$2 + lw $13,12($6) + sltu $8,$11,$2 + subu $11,$10,$11 + sltu $2,$10,$11 + sw $11,8($4) + or $2,$2,$8 + + lw $10,16($5) + addu $13,$13,$2 + lw $11,16($6) + sltu $8,$13,$2 + subu $13,$12,$13 + sltu $2,$12,$13 + sw $13,12($4) + or $2,$2,$8 + + addiu $5,$5,16 + addiu $6,$6,16 + + bne $7,$0,L(Loop) + addiu $4,$4,16 + +L(Lend): addu $11,$11,$2 + sltu $8,$11,$2 + subu $11,$10,$11 + sltu $2,$10,$11 + sw $11,0($4) + j $31 + or $2,$2,$8 + END (__mpn_sub_n) diff --git a/REORG.TODO/sysdeps/mips/submul_1.S b/REORG.TODO/sysdeps/mips/submul_1.S new file mode 100644 index 0000000000..8be8bf9007 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/submul_1.S @@ -0,0 +1,128 @@ +/* MIPS __mpn_submul_1 -- Multiply a limb vector with a single limb and +subtract the product from a second limb vector. + +Copyright (C) 1995-2017 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library. If not, see +<http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +/* INPUT PARAMETERS + res_ptr $4 + s1_ptr $5 + size $6 + s2_limb $7 +*/ +#ifdef __PIC__ + .option pic2 +#endif +ENTRY (__mpn_submul_1) + .set noreorder +#ifdef __PIC__ + .cpload t9 +#endif + .set nomacro + + /* warm up phase 0 */ + lw $8,0($5) + + /* warm up phase 1 */ + addiu $5,$5,4 +#if __mips_isa_rev < 6 + multu $8,$7 +#else + mulu $11,$8,$7 + muhu $12,$8,$7 +#endif + + addiu $6,$6,-1 + beq $6,$0,L(LC0) + move $2,$0 /* zero cy2 */ + + addiu $6,$6,-1 + beq $6,$0,L(LC1) + lw $8,0($5) /* load new s1 limb as early as possible */ + +L(Loop): lw $10,0($4) +#if __mips_isa_rev < 6 + mflo $3 + mfhi $9 +#else + move $3,$11 + move $9,$12 +#endif + addiu $5,$5,4 + addu $3,$3,$2 /* add old carry limb to low product limb */ +#if __mips_isa_rev < 6 + multu $8,$7 +#else + mulu $11,$8,$7 + muhu $12,$8,$7 +#endif + lw $8,0($5) /* load new s1 limb as early as possible */ + addiu $6,$6,-1 /* decrement loop counter */ + sltu $2,$3,$2 /* carry from previous addition -> $2 */ + subu $3,$10,$3 + sgtu $10,$3,$10 + addu $2,$2,$10 + sw $3,0($4) + addiu $4,$4,4 + bne $6,$0,L(Loop) /* should be "bnel" */ + addu $2,$9,$2 /* add high product limb and carry from addition */ + + /* cool down phase 1 */ +L(LC1): lw $10,0($4) +#if __mips_isa_rev < 6 + mflo $3 + mfhi $9 +#else + move $3,$11 + move $9,$12 +#endif + addu $3,$3,$2 + sltu $2,$3,$2 +#if __mips_isa_rev < 6 + multu $8,$7 +#else + mulu $11,$8,$7 + muhu $12,$8,$7 +#endif + subu $3,$10,$3 + sgtu $10,$3,$10 + addu $2,$2,$10 + sw $3,0($4) + addiu $4,$4,4 + addu $2,$9,$2 /* add high product limb and carry from addition */ + + /* cool down phase 0 */ +L(LC0): lw $10,0($4) +#if __mips_isa_rev < 6 + mflo $3 + mfhi $9 +#else + move $3,$11 + move $9,$12 +#endif + addu $3,$3,$2 + sltu $2,$3,$2 + subu $3,$10,$3 + sgtu $10,$3,$10 + addu $2,$2,$10 + sw $3,0($4) + j $31 + addu $2,$9,$2 /* add high product limb and carry from addition */ + END (__mpn_submul_1) diff --git a/REORG.TODO/sysdeps/mips/sys/asm.h b/REORG.TODO/sysdeps/mips/sys/asm.h new file mode 100644 index 0000000000..9e5df26f3a --- /dev/null +++ b/REORG.TODO/sysdeps/mips/sys/asm.h @@ -0,0 +1,498 @@ +/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ralf Baechle <ralf@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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_ASM_H +#define _SYS_ASM_H + +#include <sgidefs.h> + +#ifndef CAT +# define __CAT(str1,str2) str1##str2 +# define CAT(str1,str2) __CAT(str1,str2) +#endif + +/* Redefined as nonempty in the internal header. */ +#define __mips_cfi_startproc /* Empty. */ +#define __mips_cfi_endproc /* Empty. */ + +/* + * Macros to handle different pointer/register sizes for 32/64-bit code + * + * 64 bit address space isn't used yet, so we may use the R3000 32 bit + * defines for now. + */ +#if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32 +# define PTR .word +# define PTRSIZE 4 +# define PTRLOG 2 +#elif _MIPS_SIM == _ABI64 +# define PTR .dword +# define PTRSIZE 8 +# define PTRLOG 3 +#endif + +/* + * PIC specific declarations + */ +#if _MIPS_SIM == _ABIO32 +# ifdef __PIC__ +# define CPRESTORE(register) \ + .cprestore register +# define CPLOAD(register) \ + .cpload register +# else +# define CPRESTORE(register) +# define CPLOAD(register) +# endif + +# define CPADD(register) \ + .cpadd register + +/* + * Set gp when at 1st instruction + */ +# define SETUP_GP \ + .set noreorder; \ + .cpload $25; \ + .set reorder +/* Set gp when not at 1st instruction */ +# define SETUP_GPX(r) \ + .set noreorder; \ + move r, $31; /* Save old ra. */ \ + bal 10f; /* Find addr of cpload. */ \ + nop; \ +10: \ + .cpload $31; \ + move $31, r; \ + .set reorder +# define SETUP_GPX_L(r, l) \ + .set noreorder; \ + move r, $31; /* Save old ra. */ \ + bal l; /* Find addr of cpload. */ \ + nop; \ +l: \ + .cpload $31; \ + move $31, r; \ + .set reorder +# define SAVE_GP(x) \ + .cprestore x /* Save gp trigger t9/jalr conversion. */ +# define SETUP_GP64(a, b) +# define SETUP_GPX64(a, b) +# define SETUP_GPX64_L(cp_reg, ra_save, l) +# define RESTORE_GP64 +# define USE_ALT_CP(a) +#else /* _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 */ +/* + * For callee-saved gp calling convention: + */ +# define SETUP_GP +# define SETUP_GPX(r) +# define SETUP_GPX_L(r, l) +# define SAVE_GP(x) + +# define SETUP_GP64(gpoffset, proc) \ + .cpsetup $25, gpoffset, proc +# define SETUP_GPX64(cp_reg, ra_save) \ + move ra_save, $31; /* Save old ra. */ \ + .set noreorder; \ + bal 10f; /* Find addr of .cpsetup. */ \ + nop; \ +10: \ + .set reorder; \ + .cpsetup $31, cp_reg, 10b; \ + move $31, ra_save +# define SETUP_GPX64_L(cp_reg, ra_save, l) \ + move ra_save, $31; /* Save old ra. */ \ + .set noreorder; \ + bal l; /* Find addr of .cpsetup. */ \ + nop; \ +l: \ + .set reorder; \ + .cpsetup $31, cp_reg, l; \ + move $31, ra_save +# define RESTORE_GP64 \ + .cpreturn +/* Use alternate register for context pointer. */ +# define USE_ALT_CP(reg) \ + .cplocal reg +#endif /* _MIPS_SIM != _ABIO32 */ + +/* + * Stack Frame Definitions + */ +#if _MIPS_SIM == _ABIO32 +# define NARGSAVE 4 /* Space for 4 argument registers must be allocated. */ +#endif +#if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 +# define NARGSAVE 0 /* No caller responsibilities. */ +#endif + + +/* + * LEAF - declare leaf routine + */ +#define LEAF(symbol) \ + .globl symbol; \ + .align 2; \ + .type symbol,@function; \ + .ent symbol,0; \ +symbol: .frame sp,0,ra; \ + __mips_cfi_startproc + +/* + * NESTED - declare nested routine entry point + */ +#define NESTED(symbol, framesize, rpc) \ + .globl symbol; \ + .align 2; \ + .type symbol,@function; \ + .ent symbol,0; \ +symbol: .frame sp, framesize, rpc; \ + __mips_cfi_startproc + +/* + * END - mark end of function + */ +#ifndef END +# define END(function) \ + __mips_cfi_endproc; \ + .end function; \ + .size function,.-function +#endif + +/* + * EXPORT - export definition of symbol + */ +#define EXPORT(symbol) \ + .globl symbol; \ +symbol: __mips_cfi_startproc + +/* + * ABS - export absolute symbol + */ +#define ABS(symbol,value) \ + .globl symbol; \ +symbol = value + +#define PANIC(msg) \ + .set push; \ + .set reorder; \ + la a0,8f; \ + jal panic; \ +9: b 9b; \ + .set pop; \ + TEXT(msg) + +/* + * Print formated string + */ +#define PRINT(string) \ + .set push; \ + .set reorder; \ + la a0,8f; \ + jal printk; \ + .set pop; \ + TEXT(string) + +#define TEXT(msg) \ + .data; \ +8: .asciiz msg; \ + .previous; + +/* + * Build text tables + */ +#define TTABLE(string) \ + .text; \ + .word 1f; \ + .previous; \ + .data; \ +1: .asciz string; \ + .previous + +/* + * MIPS IV pref instruction. + * Use with .set noreorder only! + * + * MIPS IV implementations are free to treat this as a nop. The R5000 + * is one of them. So we should have an option not to use this instruction. + */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) +# define PREF(hint,addr) \ + pref hint,addr +# define PREFX(hint,addr) \ + prefx hint,addr +#else +# define PREF(hint,addr) +# define PREFX(hint,addr) +#endif + +/* + * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. + */ +#if _MIPS_ISA == _MIPS_ISA_MIPS1 +# define MOVN(rd,rs,rt) \ + .set push; \ + .set reorder; \ + beqz rt,9f; \ + move rd,rs; \ + .set pop; \ +9: +# define MOVZ(rd,rs,rt) \ + .set push; \ + .set reorder; \ + bnez rt,9f; \ + move rd,rt; \ + .set pop; \ +9: +#endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) +# define MOVN(rd,rs,rt) \ + .set push; \ + .set noreorder; \ + bnezl rt,9f; \ + move rd,rs; \ + .set pop; \ +9: +# define MOVZ(rd,rs,rt) \ + .set push; \ + .set noreorder; \ + beqzl rt,9f; \ + movz rd,rs; \ + .set pop; \ +9: +#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) +# define MOVN(rd,rs,rt) \ + movn rd,rs,rt +# define MOVZ(rd,rs,rt) \ + movz rd,rs,rt +#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */ + +/* + * Stack alignment + */ +#if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 +# define ALSZ 15 +# define ALMASK ~15 +#else +# define ALSZ 7 +# define ALMASK ~7 +#endif + +/* + * Size of a register + */ +#if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 +# define SZREG 8 +#else +# define SZREG 4 +#endif + +/* + * Use the following macros in assemblercode to load/store registers, + * pointers etc. + */ +#if (SZREG == 4) +# define REG_S sw +# define REG_L lw +#else +# define REG_S sd +# define REG_L ld +#endif + +/* + * How to add/sub/load/store/shift C int variables. + */ +#if (_MIPS_SZINT == 32) +# define INT_ADD add +# define INT_ADDI addi +# define INT_ADDU addu +# define INT_ADDIU addiu +# define INT_SUB sub +# define INT_SUBI subi +# define INT_SUBU subu +# define INT_SUBIU subu +# define INT_L lw +# define INT_S sw +#endif + +#if (_MIPS_SZINT == 64) +# define INT_ADD dadd +# define INT_ADDI daddi +# define INT_ADDU daddu +# define INT_ADDIU daddiu +# define INT_SUB dsub +# define INT_SUBI dsubi +# define INT_SUBU dsubu +# define INT_SUBIU dsubu +# define INT_L ld +# define INT_S sd +#endif + +/* + * How to add/sub/load/store/shift C long variables. + */ +#if (_MIPS_SZLONG == 32) +# define LONG_ADD add +# define LONG_ADDI addi +# define LONG_ADDU addu +# define LONG_ADDIU addiu +# define LONG_SUB sub +# define LONG_SUBI subi +# define LONG_SUBU subu +# define LONG_SUBIU subu +# define LONG_L lw +# define LONG_S sw +# define LONG_SLL sll +# define LONG_SLLV sllv +# define LONG_SRL srl +# define LONG_SRLV srlv +# define LONG_SRA sra +# define LONG_SRAV srav +#endif + +#if (_MIPS_SZLONG == 64) +# define LONG_ADD dadd +# define LONG_ADDI daddi +# define LONG_ADDU daddu +# define LONG_ADDIU daddiu +# define LONG_SUB dsub +# define LONG_SUBI dsubi +# define LONG_SUBU dsubu +# define LONG_SUBIU dsubu +# define LONG_L ld +# define LONG_S sd +# define LONG_SLL dsll +# define LONG_SLLV dsllv +# define LONG_SRL dsrl +# define LONG_SRLV dsrlv +# define LONG_SRA dsra +# define LONG_SRAV dsrav +#endif + +/* + * How to add/sub/load/store/shift pointers. + */ +#if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 32) +# define PTR_ADD add +# define PTR_ADDI addi +# define PTR_ADDU addu +# define PTR_ADDIU addiu +# define PTR_SUB sub +# define PTR_SUBI subi +# define PTR_SUBU subu +# define PTR_SUBIU subu +# define PTR_L lw +# define PTR_LA la +# define PTR_S sw +# define PTR_SLL sll +# define PTR_SLLV sllv +# define PTR_SRL srl +# define PTR_SRLV srlv +# define PTR_SRA sra +# define PTR_SRAV srav + +# define PTR_SCALESHIFT 2 +#endif + +#if _MIPS_SIM == _ABIN32 +# define PTR_ADD add +# define PTR_ADDI addi +# define PTR_SUB sub +# define PTR_SUBI subi +#if !defined __mips_isa_rev || __mips_isa_rev < 6 +# define PTR_ADDU add /* no u */ +# define PTR_ADDIU addi /* no u */ +# define PTR_SUBU sub /* no u */ +# define PTR_SUBIU sub /* no u */ +#else +# define PTR_ADDU addu +# define PTR_ADDIU addiu +# define PTR_SUBU subu +# define PTR_SUBIU subu +#endif +# define PTR_L lw +# define PTR_LA la +# define PTR_S sw +# define PTR_SLL sll +# define PTR_SLLV sllv +# define PTR_SRL srl +# define PTR_SRLV srlv +# define PTR_SRA sra +# define PTR_SRAV srav + +# define PTR_SCALESHIFT 2 +#endif + +#if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 64 /* o64??? */) \ + || _MIPS_SIM == _ABI64 +# define PTR_ADD dadd +# define PTR_ADDI daddi +# define PTR_ADDU daddu +# define PTR_ADDIU daddiu +# define PTR_SUB dsub +# define PTR_SUBI dsubi +# define PTR_SUBU dsubu +# define PTR_SUBIU dsubu +# define PTR_L ld +# define PTR_LA dla +# define PTR_S sd +# define PTR_SLL dsll +# define PTR_SLLV dsllv +# define PTR_SRL dsrl +# define PTR_SRLV dsrlv +# define PTR_SRA dsra +# define PTR_SRAV dsrav + +# define PTR_SCALESHIFT 3 +#endif + +/* + * Some cp0 registers were extended to 64bit for MIPS III. + */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS32) +# define MFC0 mfc0 +# define MTC0 mtc0 +#endif +#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64) +# define MFC0 dmfc0 +# define MTC0 dmtc0 +#endif + +/* The MIPS architectures do not have a uniform memory model. Particular + platforms may provide additional guarantees - for instance, the R4000 + LL and SC instructions implicitly perform a SYNC, and the 4K promises + strong ordering. + + However, in the absence of those guarantees, we must assume weak ordering + and SYNC explicitly where necessary. + + Some obsolete MIPS processors may not support the SYNC instruction. This + applies to "true" MIPS I processors; most of the processors which compile + using MIPS I implement parts of MIPS II. */ + +#ifndef MIPS_SYNC +# define MIPS_SYNC sync +#endif + +#endif /* sys/asm.h */ diff --git a/REORG.TODO/sysdeps/mips/sys/fpregdef.h b/REORG.TODO/sysdeps/mips/sys/fpregdef.h new file mode 100644 index 0000000000..01e53e9f5a --- /dev/null +++ b/REORG.TODO/sysdeps/mips/sys/fpregdef.h @@ -0,0 +1,118 @@ +/* Copyright (C) 1991-2017 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_FPREGDEF_H +#define _SYS_FPREGDEF_H + +#include <sgidefs.h> + +/* Commonalities first, individualities next... */ + +#define fv0 $f0 /* return value */ +#define fv1 $f2 + +#if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32 +#define fs0 $f20 /* callee saved */ +#define fs1 $f22 +#define fs2 $f24 +#define fs3 $f26 +#define fs4 $f28 +#define fs5 $f30 +#endif /* _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32 */ + +#if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 +#define fa0 $f12 /* argument registers */ +#define fa1 $f13 +#define fa2 $f14 +#define fa3 $f15 +#define fa4 $f16 +#define fa5 $f17 +#define fa6 $f18 +#define fa7 $f19 + +#define ft0 $f4 /* caller saved */ +#define ft1 $f5 +#define ft2 $f6 +#define ft3 $f7 +#define ft4 $f8 +#define ft5 $f9 +#define ft6 $f10 +#define ft7 $f11 +#endif /* _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 */ + +#if _MIPS_SIM == _ABIO32 +#define fv0f $f1 /* return value, high part */ +#define fv1f $f3 + +#define fa0 $f12 /* argument registers */ +#define fa0f $f13 +#define fa1 $f14 +#define fa1f $f15 + +#define ft0 $f4 /* caller saved */ +#define ft0f $f5 +#define ft1 $f6 +#define ft1f $f7 +#define ft2 $f8 +#define ft2f $f9 +#define ft3 $f10 +#define ft3f $f11 +#define ft4 $f16 +#define ft4f $f17 +#define ft5 $f18 +#define ft5f $f19 + +#define fs0f $f21 /* callee saved, high part */ +#define fs1f $f23 +#define fs2f $f25 +#define fs3f $f27 +#define fs4f $f29 +#define fs5f $f31 +#endif /* _MIPS_SIM == _ABIO32 */ + +#if _MIPS_SIM == _ABI64 +#define ft8 $f20 /* caller saved */ +#define ft9 $f21 +#define ft10 $f22 +#define ft11 $f23 +#define ft12 $f1 +#define ft13 $f3 + +#define fs0 $f24 /* callee saved */ +#define fs1 $f25 +#define fs2 $f26 +#define fs3 $f27 +#define fs4 $f28 +#define fs5 $f29 +#define fs6 $f30 +#define fs7 $f31 +#endif /* _MIPS_SIM == _ABI64 */ + +#if _MIPS_SIM == _ABIN32 +#define ft8 $f21 /* caller saved */ +#define ft9 $f23 +#define ft10 $f25 +#define ft11 $f27 +#define ft12 $f29 +#define ft13 $f31 +#define ft14 $f1 +#define ft15 $f3 +#endif /* _MIPS_SIM == _ABIN32 */ + +#define fcr31 $31 /* FPU status register */ + +#endif /* sys/fpregdef.h */ diff --git a/REORG.TODO/sysdeps/mips/sys/regdef.h b/REORG.TODO/sysdeps/mips/sys/regdef.h new file mode 100644 index 0000000000..f938345056 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/sys/regdef.h @@ -0,0 +1,81 @@ +/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ralf Baechle <ralf@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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_REGDEF_H +#define _SYS_REGDEF_H + +#include <sgidefs.h> + +/* + * Symbolic register names for 32 bit ABI + */ +#define zero $0 /* wired zero */ +#define AT $1 /* assembler temp - uppercase because of ".set at" */ +#define v0 $2 /* return value */ +#define v1 $3 +#define a0 $4 /* argument registers */ +#define a1 $5 +#define a2 $6 +#define a3 $7 +#if _MIPS_SIM != _ABIO32 +#define a4 $8 +#define a5 $9 +#define a6 $10 +#define a7 $11 +#define t0 $12 +#define t1 $13 +#define t2 $14 +#define t3 $15 +#define ta0 a4 +#define ta1 a5 +#define ta2 a6 +#define ta3 a7 +#else /* if _MIPS_SIM == _ABIO32 */ +#define t0 $8 /* caller saved */ +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define ta0 t4 +#define ta1 t5 +#define ta2 t6 +#define ta3 t7 +#endif /* _MIPS_SIM == _ABIO32 */ +#define s0 $16 /* callee saved */ +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define t8 $24 /* caller saved */ +#define t9 $25 +#define jp $25 /* PIC jump register */ +#define k0 $26 /* kernel scratch */ +#define k1 $27 +#define gp $28 /* global pointer */ +#define sp $29 /* stack pointer */ +#define fp $30 /* frame pointer */ +#define s8 $30 /* same like fp! */ +#define ra $31 /* return address */ + +#endif /* _SYS_REGDEF_H */ diff --git a/REORG.TODO/sysdeps/mips/sys/tas.h b/REORG.TODO/sysdeps/mips/sys/tas.h new file mode 100644 index 0000000000..3e020a754e --- /dev/null +++ b/REORG.TODO/sysdeps/mips/sys/tas.h @@ -0,0 +1,69 @@ +/* Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Maciej W. Rozycki <macro@ds2.pg.gda.pl>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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_TAS_H +#define _SYS_TAS_H 1 + +#include <features.h> +#include <sgidefs.h> + +__BEGIN_DECLS + +extern int _test_and_set (int *__p, int __v) + __THROW __attribute__ ((__nomips16__)); + +#ifdef __USE_EXTERN_INLINES + +# ifndef _EXTERN_INLINE +# define _EXTERN_INLINE __extern_inline +# endif + +_EXTERN_INLINE int __attribute__ ((__nomips16__)) +__NTH (_test_and_set (int *__p, int __v)) +{ + int __r, __t; + + __asm__ __volatile__ + ("/* Inline test and set */\n" + ".set push\n\t" +#if _MIPS_SIM == _ABIO32 && __mips < 2 + ".set mips2\n\t" +#endif + "sync\n\t" + "1:\n\t" + "ll %0,%3\n\t" + "move %1,%4\n\t" + "beq %0,%4,2f\n\t" + "sc %1,%2\n\t" + "beqz %1,1b\n" + "sync\n\t" + ".set pop\n\t" + "2:\n\t" + "/* End test and set */" + : "=&r" (__r), "=&r" (__t), "=m" (*__p) + : "m" (*__p), "r" (__v) + : "memory"); + + return __r; +} + +#endif /* __USE_EXTERN_INLINES */ + +__END_DECLS + +#endif /* sys/tas.h */ diff --git a/REORG.TODO/sysdeps/mips/sys/ucontext.h b/REORG.TODO/sysdeps/mips/sys/ucontext.h new file mode 100644 index 0000000000..4bc1bc199a --- /dev/null +++ b/REORG.TODO/sysdeps/mips/sys/ucontext.h @@ -0,0 +1,176 @@ +/* Copyright (C) 1998-2017 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/>. */ + +/* System V/mips ABI compliant context switching support. */ + +#ifndef _SYS_UCONTEXT_H +#define _SYS_UCONTEXT_H 1 + +#include <features.h> + +#include <bits/types/sigset_t.h> +#include <bits/sigcontext.h> +#include <bits/types/stack_t.h> + +#include <sgidefs.h> + + +/* Type for general register. */ +#if _MIPS_SIM == _ABIO32 +typedef __uint32_t greg_t; +#else +typedef __uint64_t greg_t; +#endif + +/* Number of general registers. */ +#define __NGREG 36 +#ifdef __USE_MISC +# define NGREG __NGREG +#endif + +/* Container for all general registers. */ +typedef greg_t gregset_t[__NGREG]; + +#ifdef __USE_MISC +/* Number of each register is the `gregset_t' array. */ +enum +{ + CTX_R0 = 0, +# define CTX_R0 CTX_R0 + CTX_AT = 1, +# define CTX_AT CTX_AT + CTX_V0 = 2, +# define CTX_V0 CTX_V0 + CTX_V1 = 3, +# define CTX_V1 CTX_V1 + CTX_A0 = 4, +# define CTX_A0 CTX_A0 + CTX_A1 = 5, +# define CTX_A1 CTX_A1 + CTX_A2 = 6, +# define CTX_A2 CTX_A2 + CTX_A3 = 7, +# define CTX_A3 CTX_A3 + CTX_T0 = 8, +# define CTX_T0 CTX_T0 + CTX_T1 = 9, +# define CTX_T1 CTX_T1 + CTX_T2 = 10, +# define CTX_T2 CTX_T2 + CTX_T3 = 11, +# define CTX_T3 CTX_T3 + CTX_T4 = 12, +# define CTX_T4 CTX_T4 + CTX_T5 = 13, +# define CTX_T5 CTX_T5 + CTX_T6 = 14, +# define CTX_T6 CTX_T6 + CTX_T7 = 15, +# define CTX_T7 CTX_T7 + CTX_S0 = 16, +# define CTX_S0 CTX_S0 + CTX_S1 = 17, +# define CTX_S1 CTX_S1 + CTX_S2 = 18, +# define CTX_S2 CTX_S2 + CTX_S3 = 19, +# define CTX_S3 CTX_S3 + CTX_S4 = 20, +# define CTX_S4 CTX_S4 + CTX_S5 = 21, +# define CTX_S5 CTX_S5 + CTX_S6 = 22, +# define CTX_S6 CTX_S6 + CTX_S7 = 23, +# define CTX_S7 CTX_S7 + CTX_T8 = 24, +# define CTX_T8 CTX_T8 + CTX_T9 = 25, +# define CTX_T9 CTX_T9 + CTX_K0 = 26, +# define CTX_K0 CTX_K0 + CTX_K1 = 27, +# define CTX_K1 CTX_K1 + CTX_GP = 28, +# define CTX_GP CTX_GP + CTX_SP = 29, +# define CTX_SP CTX_SP + CTX_S8 = 30, +# define CTX_S8 CTX_S8 + CTX_RA = 31, +# define CTX_RA CTX_RA + CTX_MDLO = 32, +# define CTX_MDLO CTX_MDLO + CTX_MDHI = 33, +# define CTX_MDHI CTX_MDHI + CTX_CAUSE = 34, +# define CTX_CAUSE CTX_CAUSE + CTX_EPC = 35, +# define CTX_EPC CTX_EPC +}; +#endif + +#ifdef __USE_MISC +# define __ctx(fld) fld +#else +# define __ctx(fld) __ ## fld +#endif + +/* Structure to describe FPU registers. */ +typedef struct fpregset +{ + union + { +#if _MIPS_SIM == _ABIO32 + double __ctx(fp_dregs)[16]; + float __ctx(fp_fregs)[32]; + unsigned int __ctx(fp_regs)[32]; +#else + double __ctx(fp_dregs)[32]; + /* float __ctx(fp_fregs)[32]; */ + __uint64_t __ctx(fp_regs)[32]; +#endif + } __ctx(fp_r); + unsigned int __ctx(fp_csr); + unsigned int __ctx(fp_pad); +} fpregset_t; + +/* Context to describe whole processor state. */ +typedef struct +{ + gregset_t __ctx(gpregs); + fpregset_t __ctx(fpregs); +} mcontext_t; + +#undef __ctx + +/* Userlevel context. */ +typedef struct ucontext +{ +#if _MIPS_SIM == _ABIO32 + unsigned long int uc_flags; +#else + __uint64_t uc_flags; +#endif + struct ucontext *uc_link; + sigset_t uc_sigmask; + stack_t uc_stack; + mcontext_t uc_mcontext; + int uc_filler[48]; +} ucontext_t; + +#endif /* sys/ucontext.h */ diff --git a/REORG.TODO/sysdeps/mips/tininess.h b/REORG.TODO/sysdeps/mips/tininess.h new file mode 100644 index 0000000000..1db37790f8 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/tininess.h @@ -0,0 +1 @@ +#define TININESS_AFTER_ROUNDING 1 diff --git a/REORG.TODO/sysdeps/mips/tls-macros.h b/REORG.TODO/sysdeps/mips/tls-macros.h new file mode 100644 index 0000000000..a6fdfbc0ad --- /dev/null +++ b/REORG.TODO/sysdeps/mips/tls-macros.h @@ -0,0 +1,130 @@ +/* Macros to support TLS testing in times of missing compiler support. */ + +#include <sys/cdefs.h> +#include <sys/asm.h> +#include <sysdep.h> + +#define __STRING2(X) __STRING(X) +#define ADDU __STRING2(PTR_ADDU) +#define ADDIU __STRING2(PTR_ADDIU) +#define LW __STRING2(PTR_L) + +/* Load the GOT pointer, which may not be in $28 in a non-PIC + (abicalls pic0) function. */ +#ifndef __PIC__ +# if _MIPS_SIM != _ABI64 +# ifndef __mips16 +# define LOAD_GP "move %[tmp], $28\n\tla $28, __gnu_local_gp\n\t" +# else +# define LOAD_GP \ + "li %[tmp], %%hi(__gnu_local_gp)\n\t" \ + "sll %[tmp], 16\n\t" \ + "addiu %[tmp], %%lo(__gnu_local_gp)\n\t" +# endif +# else +# define LOAD_GP "move %[tmp], $28\n\tdla $28, __gnu_local_gp\n\t" +# endif +# define UNLOAD_GP "\n\tmove $28, %[tmp]" +#else +/* MIPS16 (re)creates the GP value using PC-relative instructions. */ +# ifdef __mips16 +# define LOAD_GP \ + "li %[tmp], %%hi(_gp_disp)\n\t" \ + "addiu %0, $pc, %%lo(_gp_disp)\n\t" \ + "sll %[tmp], 16\n\t" \ + "addu %[tmp], %0\n\t" +# else +# define LOAD_GP +# endif +# define UNLOAD_GP +#endif + +# if __mips_isa_rev >= 2 +# define TLS_RDHWR "rdhwr\t%0,$29" +# else +# define TLS_RDHWR \ + ".set push\n\t.set mips32r2\n\t" \ + "rdhwr\t%0,$29\n\t.set pop" +#endif + +#ifndef __mips16 +# define TLS_GD(x) \ + ({ void *__result, *__tmp; \ + extern void *__tls_get_addr (void *); \ + asm (LOAD_GP ADDIU " %0, $28, %%tlsgd(" #x ")" \ + UNLOAD_GP \ + : "=r" (__result), [tmp] "=&r" (__tmp)); \ + (int *)__tls_get_addr (__result); }) +# define TLS_LD(x) \ + ({ void *__result, *__tmp; \ + extern void *__tls_get_addr (void *); \ + asm (LOAD_GP ADDIU " %0, $28, %%tlsldm(" #x ")" \ + UNLOAD_GP \ + : "=r" (__result), [tmp] "=&r" (__tmp)); \ + __result = __tls_get_addr (__result); \ + asm ("lui $3,%%dtprel_hi(" #x ")\n\t" \ + "addiu $3,$3,%%dtprel_lo(" #x ")\n\t" \ + ADDU " %0,%0,$3" \ + : "+r" (__result) : : "$3"); \ + __result; }) +# define TLS_IE(x) \ + ({ void *__result, *__tmp; \ + asm (TLS_RDHWR \ + : "=v" (__result)); \ + asm (LOAD_GP LW " $3,%%gottprel(" #x ")($28)\n\t" \ + ADDU " %0,%0,$3" \ + UNLOAD_GP \ + : "+r" (__result), [tmp] "=&r" (__tmp) \ + : : "$3"); \ + __result; }) +# define TLS_LE(x) \ + ({ void *__result; \ + asm (TLS_RDHWR \ + : "=v" (__result)); \ + asm ("lui $3,%%tprel_hi(" #x ")\n\t" \ + "addiu $3,$3,%%tprel_lo(" #x ")\n\t" \ + ADDU " %0,%0,$3" \ + : "+r" (__result) : : "$3"); \ + __result; }) + +#else /* __mips16 */ +/* MIPS16 version. */ +# define TLS_GD(x) \ + ({ void *__result, *__tmp; \ + extern void *__tls_get_addr (void *); \ + asm (LOAD_GP ADDIU " %1, %%tlsgd(" #x ")" \ + "\n\tmove %0, %1" \ + : "=d" (__result), [tmp] "=&d" (__tmp)); \ + (int *) __tls_get_addr (__result); }) +# define TLS_LD(x) \ + ({ void *__result, *__tmp; \ + extern void *__tls_get_addr (void *); \ + asm (LOAD_GP ADDIU " %1, %%tlsldm(" #x ")" \ + "\n\tmove %0, %1" \ + : "=d" (__result), [tmp] "=&d" (__tmp)); \ + __result = __tls_get_addr (__result); \ + asm ("li $3,%%dtprel_hi(" #x ")\n\t" \ + "sll $3,16\n\t" \ + "addiu $3,%%dtprel_lo(" #x ")\n\t" \ + ADDU " %0,%0,$3" \ + : "+d" (__result) : : "$3"); \ + __result; }) +# define TLS_IE(x) \ + ({ void *__result, *__tmp, *__tp; \ + __tp = __builtin_thread_pointer (); \ + asm (LOAD_GP LW " $3,%%gottprel(" #x ")(%1)\n\t" \ + ADDU " %0,%[tp],$3" \ + : "=&d" (__result), [tmp] "=&d" (__tmp) \ + : [tp] "d" (__tp) : "$3"); \ + __result; }) +# define TLS_LE(x) \ + ({ void *__result, *__tp; \ + __tp = __builtin_thread_pointer (); \ + asm ("li $3,%%tprel_hi(" #x ")\n\t" \ + "sll $3,16\n\t" \ + "addiu $3,%%tprel_lo(" #x ")\n\t" \ + ADDU " %0,%[tp],$3" \ + : "=d" (__result) : [tp] "d" (__tp) : "$3"); \ + __result; }) + +#endif /* __mips16 */ diff --git a/REORG.TODO/sysdeps/mips/tst-abi-fp32mod.c b/REORG.TODO/sysdeps/mips/tst-abi-fp32mod.c new file mode 100644 index 0000000000..2df4070fc2 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/tst-abi-fp32mod.c @@ -0,0 +1,22 @@ +/* Copyright (C) 2014-2017 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/>. */ + +int +fp32 (void) +{ + return 1; +} diff --git a/REORG.TODO/sysdeps/mips/tst-abi-fp64amod.c b/REORG.TODO/sysdeps/mips/tst-abi-fp64amod.c new file mode 100644 index 0000000000..c724d53bf2 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/tst-abi-fp64amod.c @@ -0,0 +1,22 @@ +/* Copyright (C) 2014-2017 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/>. */ + +int +fp64a (void) +{ + return 7; +} diff --git a/REORG.TODO/sysdeps/mips/tst-abi-fp64mod.c b/REORG.TODO/sysdeps/mips/tst-abi-fp64mod.c new file mode 100644 index 0000000000..c4d5ab72ae --- /dev/null +++ b/REORG.TODO/sysdeps/mips/tst-abi-fp64mod.c @@ -0,0 +1,22 @@ +/* Copyright (C) 2014-2017 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/>. */ + +int +fp64 (void) +{ + return 6; +} diff --git a/REORG.TODO/sysdeps/mips/tst-abi-fpxxmod.c b/REORG.TODO/sysdeps/mips/tst-abi-fpxxmod.c new file mode 100644 index 0000000000..a2de29735e --- /dev/null +++ b/REORG.TODO/sysdeps/mips/tst-abi-fpxxmod.c @@ -0,0 +1,22 @@ +/* Copyright (C) 2014-2017 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/>. */ + +int +fpxx (void) +{ + return 5; +} diff --git a/REORG.TODO/sysdeps/mips/tst-abi-fpxxomod.c b/REORG.TODO/sysdeps/mips/tst-abi-fpxxomod.c new file mode 100644 index 0000000000..b43190eb03 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/tst-abi-fpxxomod.c @@ -0,0 +1,22 @@ +/* Copyright (C) 2014-2017 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/>. */ + +int +fpxxo (void) +{ + return 5 + 100; +} diff --git a/REORG.TODO/sysdeps/mips/tst-abi-interlink.c b/REORG.TODO/sysdeps/mips/tst-abi-interlink.c new file mode 100644 index 0000000000..32aa861191 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/tst-abi-interlink.c @@ -0,0 +1,844 @@ +/* Copyright (C) 2014-2017 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/>. */ + +#include <sys/prctl.h> +#include <dlfcn.h> +#include <stdio.h> +#include <string.h> +#include <stdbool.h> +#include <errno.h> + +#if defined PR_GET_FP_MODE && defined PR_SET_FP_MODE +# define HAVE_PRCTL_FP_MODE 1 +# define FR1_MODE (PR_FP_MODE_FR) +# define FRE_MODE (PR_FP_MODE_FR | PR_FP_MODE_FRE) +#else +# define HAVE_PRCTL_FP_MODE 0 +# define FR1_MODE 0x1 +# define FRE_MODE 0x2 +#endif + +#define STR_VAL(VAL) #VAL +#define N_STR(VAL) STR_VAL(VAL) + +#define START_STATE(NAME) \ +case s_ ## NAME: \ + { \ + switch (obj) \ + { + +#define END_STATE \ + default: \ + return false; \ + } \ + break; \ + } + +#define NEXT(OBJ, NEXT_STATE) \ +case o_ ## OBJ: \ + current_fp_state = s_ ## NEXT_STATE; \ + break; + +#define NEXT_REQ_FR1(OBJ, NEXT_STATE) \ +case o_ ## OBJ: \ + { \ + if (has_fr1) \ + current_fp_state = s_ ## NEXT_STATE; \ + else \ + return false; \ + } \ + break; + +#define NEXT_REQ_FR0(OBJ, NEXT_STATE) \ +case o_ ## OBJ: \ + { \ + if (!is_r6 \ + || (is_r6 && has_fr1 && has_fre)) \ + current_fp_state = s_ ## NEXT_STATE; \ + else \ + return false; \ + } \ + break; + +#define NEXT_REQ_FRE(OBJ, NEXT_STATE) \ +case o_ ## OBJ: \ + { \ + if (has_fr1 && has_fre) \ + current_fp_state = s_ ## NEXT_STATE; \ + else \ + return false; \ + } \ + break; + +#define NEXT_NO_MODE_CHANGE(OBJ, NEXT_STATE) \ +case o_ ## OBJ: \ + { \ + if (current_mode_valid_p (s_ ## NEXT_STATE)) \ + { \ + current_fp_state = s_ ## NEXT_STATE; \ + cant_change_mode = true; \ + } \ + else \ + return false; \ + } \ + break; + +static const char * const shared_lib_names[] = + { + "tst-abi-fpanymod.so", "tst-abi-fpsoftmod.so", "tst-abi-fpsinglemod.so", + "tst-abi-fp32mod.so", "tst-abi-fp64mod.so", "tst-abi-fp64amod.so", + "tst-abi-fpxxmod.so", "tst-abi-fpxxomod.so" + }; + +struct fp_mode_req +{ + int mode1; + int mode2; + int mode3; +}; + +enum fp_obj +{ + o_any, + o_soft, + o_single, + o_fp32, + o_fp64, + o_fp64a, + o_fpxx, + o_fpxxo, + o_max +}; + +enum fp_state +{ + s_any, + s_soft, + s_single, + s_fp32, + s_fpxx, + s_fpxxo, + s_fp64a, + s_fp64, + s_fpxxo_fpxx, + s_fp32_fpxx, + s_fp32_fpxxo, + s_fp32_fpxxo_fpxx, + s_fp32_fp64a_fpxx, + s_fp32_fp64a_fpxxo, + s_fp32_fp64a_fpxxo_fpxx, + s_fp64a_fp32, + s_fp64a_fpxx, + s_fp64a_fpxxo, + s_fp64a_fp64, + s_fp64a_fp64_fpxx, + s_fp64a_fp64_fpxxo, + s_fp64a_fpxx_fpxxo, + s_fp64a_fp64_fpxxo_fpxx, + s_fp64_fpxx, + s_fp64_fpxxo, + s_fp64_fpxx_fpxxo +}; + + +static int current_fp_mode; +static bool cant_change_mode = false; +static bool has_fr1 = false; +static bool has_fre = false; +static bool is_r6 = false; +static unsigned int fp_obj_count[o_max]; +void * shared_lib_ptrs[o_max]; +static enum fp_state current_fp_state = s_any; +static enum fp_obj test_objects[FPABI_COUNT] = { FPABI_LIST }; + +/* This function will return the valid FP modes for the specified state. */ + +static struct fp_mode_req +compute_fp_modes (enum fp_state state) +{ + struct fp_mode_req requirements; + + requirements.mode1 = -1; + requirements.mode2 = -1; + requirements.mode3 = -1; + + switch (state) + { + case s_single: + { + if (is_r6) + requirements.mode1 = FR1_MODE; + else + { + requirements.mode1 = 0; + requirements.mode2 = FR1_MODE; + } + break; + } + case s_fp32: + case s_fp32_fpxx: + case s_fp32_fpxxo: + case s_fp32_fpxxo_fpxx: + { + if (is_r6) + requirements.mode1 = FRE_MODE; + else + { + requirements.mode1 = 0; + requirements.mode2 = FRE_MODE; + } + break; + } + case s_fpxx: + case s_fpxxo: + case s_fpxxo_fpxx: + case s_any: + case s_soft: + { + if (is_r6) + { + requirements.mode1 = FR1_MODE; + requirements.mode2 = FRE_MODE; + } + else + { + requirements.mode1 = 0; + requirements.mode2 = FR1_MODE; + requirements.mode3 = FRE_MODE; + } + break; + } + case s_fp64a: + case s_fp64a_fpxx: + case s_fp64a_fpxxo: + case s_fp64a_fpxx_fpxxo: + { + requirements.mode1 = FR1_MODE; + requirements.mode2 = FRE_MODE; + break; + } + case s_fp64: + case s_fp64_fpxx: + case s_fp64_fpxxo: + case s_fp64_fpxx_fpxxo: + case s_fp64a_fp64: + case s_fp64a_fp64_fpxx: + case s_fp64a_fp64_fpxxo: + case s_fp64a_fp64_fpxxo_fpxx: + { + requirements.mode1 = FR1_MODE; + break; + } + case s_fp64a_fp32: + case s_fp32_fp64a_fpxx: + case s_fp32_fp64a_fpxxo: + case s_fp32_fp64a_fpxxo_fpxx: + { + requirements.mode1 = FRE_MODE; + break; + } + } + return requirements; +} + +/* Check the current mode is suitable for the specified state. */ + +static bool +current_mode_valid_p (enum fp_state s) +{ + struct fp_mode_req req = compute_fp_modes (s); + return (req.mode1 == current_fp_mode + || req.mode2 == current_fp_mode + || req.mode3 == current_fp_mode); +} + +/* Run the state machine by adding a new object. */ + +static bool +set_next_fp_state (enum fp_obj obj) +{ + cant_change_mode = false; + switch (current_fp_state) + { + + START_STATE(soft) + NEXT(soft,soft) + NEXT(any,soft) + END_STATE + + START_STATE(single) + NEXT(single,single) + NEXT(any,single) + END_STATE + + START_STATE(any) + NEXT_REQ_FR0(fp32, fp32) + NEXT(fpxx, fpxx) + NEXT(fpxxo, fpxxo) + NEXT_REQ_FR1(fp64a, fp64a) + NEXT_REQ_FR1(fp64, fp64) + NEXT(any,any) + NEXT(soft,soft) + NEXT(single,single) + END_STATE + + START_STATE(fp32) + NEXT_REQ_FR0(fp32,fp32) + NEXT(fpxx, fp32_fpxx) + NEXT(fpxxo, fp32_fpxxo) + NEXT_REQ_FRE(fp64a, fp64a_fp32) + NEXT(any,fp32) + END_STATE + + START_STATE(fpxx) + NEXT_REQ_FR0(fp32, fp32_fpxx) + NEXT_REQ_FR1(fp64, fp64_fpxx) + NEXT_REQ_FR1(fp64a, fp64a_fpxx) + NEXT(fpxxo, fpxxo_fpxx) + NEXT(fpxx,fpxx) + NEXT(any,fpxx) + END_STATE + + START_STATE(fpxxo) + NEXT_NO_MODE_CHANGE(fp32, fp32_fpxxo) + NEXT_NO_MODE_CHANGE(fp64, fp64_fpxxo) + NEXT_NO_MODE_CHANGE(fp64a, fp64a_fpxxo) + NEXT_NO_MODE_CHANGE(fpxx, fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fpxxo,fpxxo) + NEXT_NO_MODE_CHANGE(any,fpxxo) + END_STATE + + START_STATE(fp64a) + NEXT_REQ_FRE(fp32, fp64a_fp32) + NEXT_REQ_FR1(fp64, fp64a_fp64) + NEXT(fpxxo, fp64a_fpxxo) + NEXT(fpxx, fp64a_fpxx) + NEXT_REQ_FR1(fp64a, fp64a) + NEXT(any, fp64a) + END_STATE + + START_STATE(fp64) + NEXT_REQ_FR1(fp64a, fp64a_fp64) + NEXT(fpxxo, fp64_fpxxo) + NEXT(fpxx, fp64_fpxx) + NEXT_REQ_FR1(fp64, fp64) + NEXT(any, fp64) + END_STATE + + START_STATE(fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fp32, fp32_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fp64, fp64_fpxx_fpxxo) + NEXT_NO_MODE_CHANGE(fp64a, fp64a_fpxx_fpxxo) + NEXT_NO_MODE_CHANGE(fpxx, fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fpxxo, fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(any, fpxxo_fpxx) + END_STATE + + START_STATE(fp32_fpxx) + NEXT_REQ_FR0(fp32, fp32_fpxx) + NEXT(fpxx, fp32_fpxx) + NEXT(fpxxo, fp32_fpxxo_fpxx) + NEXT_REQ_FRE(fp64a, fp32_fp64a_fpxx) + NEXT(any, fp32_fpxx) + END_STATE + + START_STATE(fp32_fpxxo) + NEXT_NO_MODE_CHANGE(fp32, fp32_fpxxo) + NEXT_NO_MODE_CHANGE(fpxxo, fp32_fpxxo) + NEXT_NO_MODE_CHANGE(fpxx, fp32_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fp64a, fp32_fp64a_fpxxo) + NEXT_NO_MODE_CHANGE(any, fp32_fpxxo) + END_STATE + + START_STATE(fp32_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fp32, fp32_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fpxxo, fp32_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fpxx, fp32_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fp64a, fp32_fp64a_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(any, fp32_fpxxo_fpxx) + END_STATE + + START_STATE(fp64a_fp32) + NEXT_REQ_FRE(fp32, fp64a_fp32) + NEXT_REQ_FRE(fp64a, fp64a_fp32) + NEXT(fpxxo, fp32_fp64a_fpxxo) + NEXT(fpxx, fp32_fp64a_fpxx) + NEXT(any, fp64a_fp32) + END_STATE + + START_STATE(fp64a_fpxx) + NEXT_REQ_FRE(fp32, fp32_fp64a_fpxx) + NEXT_REQ_FR1(fp64a, fp64a_fpxx) + NEXT(fpxx, fp64a_fpxx) + NEXT(fpxxo, fp64a_fpxx_fpxxo) + NEXT_REQ_FR1(fp64, fp64a_fp64_fpxx) + NEXT(any, fp64a_fpxx) + END_STATE + + START_STATE(fp64a_fpxxo) + NEXT_NO_MODE_CHANGE(fp32, fp32_fp64a_fpxxo) + NEXT_NO_MODE_CHANGE(fp64a, fp64a_fpxxo) + NEXT_NO_MODE_CHANGE(fpxx, fp64a_fpxx_fpxxo) + NEXT_NO_MODE_CHANGE(fpxxo, fp64a_fpxxo) + NEXT_NO_MODE_CHANGE(fp64, fp64a_fp64_fpxxo) + NEXT_NO_MODE_CHANGE(any, fp64a_fpxxo) + END_STATE + + START_STATE(fp64a_fpxx_fpxxo) + NEXT_NO_MODE_CHANGE(fp32, fp32_fp64a_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fp64a, fp64a_fpxx_fpxxo) + NEXT_NO_MODE_CHANGE(fpxx, fp64a_fpxx_fpxxo) + NEXT_NO_MODE_CHANGE(fpxxo, fp64a_fpxx_fpxxo) + NEXT_NO_MODE_CHANGE(fp64, fp64a_fp64_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(any, fp64a_fpxx_fpxxo) + END_STATE + + START_STATE(fp64_fpxx) + NEXT_REQ_FR1(fp64a, fp64a_fp64_fpxx) + NEXT(fpxxo, fp64_fpxx_fpxxo) + NEXT(fpxx, fp64_fpxx) + NEXT_REQ_FR1(fp64, fp64_fpxx) + NEXT(any, fp64_fpxx) + END_STATE + + START_STATE(fp64_fpxxo) + NEXT_NO_MODE_CHANGE(fp64a, fp64a_fp64_fpxxo) + NEXT_NO_MODE_CHANGE(fpxxo, fp64_fpxxo) + NEXT_NO_MODE_CHANGE(fpxx, fp64_fpxx_fpxxo) + NEXT_NO_MODE_CHANGE(fp64, fp64_fpxxo) + NEXT_NO_MODE_CHANGE(any, fp64_fpxxo) + END_STATE + + START_STATE(fp64_fpxx_fpxxo) + NEXT_NO_MODE_CHANGE(fp64a, fp64a_fp64_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fpxxo, fp64_fpxx_fpxxo) + NEXT_NO_MODE_CHANGE(fpxx, fp64_fpxx_fpxxo) + NEXT_NO_MODE_CHANGE(fp64, fp64_fpxx_fpxxo) + NEXT_NO_MODE_CHANGE(any, fp64_fpxx_fpxxo) + END_STATE + + START_STATE(fp64a_fp64) + NEXT_REQ_FR1(fp64a, fp64a_fp64) + NEXT(fpxxo, fp64a_fp64_fpxxo) + NEXT(fpxx, fp64a_fp64_fpxx) + NEXT_REQ_FR1(fp64, fp64a_fp64) + NEXT(any, fp64a_fp64) + END_STATE + + START_STATE(fp64a_fp64_fpxx) + NEXT_REQ_FR1(fp64a, fp64a_fp64_fpxx) + NEXT(fpxxo, fp64a_fp64_fpxxo_fpxx) + NEXT(fpxx, fp64a_fp64_fpxx) + NEXT_REQ_FR1(fp64, fp64a_fp64_fpxx) + NEXT(any, fp64a_fp64_fpxx) + END_STATE + + START_STATE(fp64a_fp64_fpxxo) + NEXT_NO_MODE_CHANGE(fp64a, fp64a_fp64_fpxxo) + NEXT_NO_MODE_CHANGE(fpxx, fp64a_fp64_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fpxxo, fp64a_fp64_fpxxo) + NEXT_NO_MODE_CHANGE(fp64, fp64a_fp64_fpxxo) + NEXT_NO_MODE_CHANGE(any, fp64a_fp64_fpxxo) + END_STATE + + START_STATE(fp64a_fp64_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fp64a, fp64a_fp64_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fpxx, fp64a_fp64_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fpxxo, fp64a_fp64_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fp64, fp64a_fp64_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(any, fp64a_fp64_fpxxo_fpxx) + END_STATE + + START_STATE(fp32_fp64a_fpxx) + NEXT_REQ_FRE(fp32, fp32_fp64a_fpxx) + NEXT_REQ_FRE(fp64a, fp32_fp64a_fpxx) + NEXT(fpxxo, fp32_fp64a_fpxxo_fpxx) + NEXT(fpxx, fp32_fp64a_fpxx) + NEXT(any, fp32_fp64a_fpxx) + END_STATE + + START_STATE(fp32_fp64a_fpxxo) + NEXT_NO_MODE_CHANGE(fp32, fp32_fp64a_fpxxo) + NEXT_NO_MODE_CHANGE(fp64a, fp32_fp64a_fpxxo) + NEXT_NO_MODE_CHANGE(fpxx, fp32_fp64a_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fpxxo, fp32_fp64a_fpxxo) + NEXT_NO_MODE_CHANGE(any, fp32_fp64a_fpxxo) + END_STATE + + START_STATE(fp32_fp64a_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fp32, fp32_fp64a_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fp64a, fp32_fp64a_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fpxx, fp32_fp64a_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(fpxxo, fp32_fp64a_fpxxo_fpxx) + NEXT_NO_MODE_CHANGE(any, fp32_fp64a_fpxxo_fpxx) + END_STATE + } + + if (obj != o_max) + fp_obj_count[obj]++; + + return true; +} + +/* Run the state machine by removing an object. */ + +static bool +remove_object (enum fp_obj obj) +{ + if (obj == o_max) + return false; + + fp_obj_count[obj]--; + + /* We can't change fp state until all the objects + of a particular type have been unloaded. */ + if (fp_obj_count[obj] != 0) + return false; + + switch (current_fp_state) + { + START_STATE(soft) + NEXT(soft,any) + END_STATE + + START_STATE(single) + NEXT(single,any) + END_STATE + + START_STATE(any) + NEXT(any,any) + END_STATE + + START_STATE(fp32) + NEXT (fp32,any) + END_STATE + + START_STATE(fpxx) + NEXT (fpxx,any) + END_STATE + + START_STATE(fpxxo) + NEXT (fpxxo,any) + END_STATE + + START_STATE(fp64a) + NEXT(fp64a, any) + END_STATE + + START_STATE(fp64) + NEXT(fp64, any) + END_STATE + + START_STATE(fpxxo_fpxx) + NEXT(fpxx, fpxxo) + NEXT(fpxxo, fpxx) + END_STATE + + START_STATE(fp32_fpxx) + NEXT(fp32, fpxx) + NEXT(fpxx, fp32) + END_STATE + + START_STATE(fp32_fpxxo) + NEXT(fp32, fpxxo) + NEXT(fpxxo, fp32) + END_STATE + + START_STATE(fp32_fpxxo_fpxx) + NEXT(fp32, fpxxo_fpxx) + NEXT(fpxxo, fp32_fpxx) + NEXT(fpxx, fp32_fpxxo) + END_STATE + + START_STATE(fp64a_fp32) + NEXT(fp32, fp64a) + NEXT(fp64a, fp32) + END_STATE + + START_STATE(fp64a_fpxx) + NEXT(fp64a, fpxx) + NEXT(fpxx, fp64a) + END_STATE + + START_STATE(fp64a_fpxxo) + NEXT(fp64a, fpxxo) + NEXT(fpxxo, fp64a) + END_STATE + + START_STATE(fp64a_fpxx_fpxxo) + NEXT(fp64a, fpxxo_fpxx) + NEXT(fpxx, fp64a_fpxxo) + NEXT(fpxxo, fp64a_fpxx) + END_STATE + + START_STATE(fp64_fpxx) + NEXT(fpxx, fp64) + NEXT(fp64, fpxx) + END_STATE + + START_STATE(fp64_fpxxo) + NEXT(fpxxo, fp64) + NEXT(fp64, fpxxo) + END_STATE + + START_STATE(fp64_fpxx_fpxxo) + NEXT(fp64, fpxxo_fpxx) + NEXT(fpxxo, fp64_fpxx) + NEXT(fpxx, fp64_fpxxo) + END_STATE + + START_STATE(fp64a_fp64) + NEXT(fp64a, fp64) + NEXT(fp64, fp64a) + END_STATE + + START_STATE(fp64a_fp64_fpxx) + NEXT(fp64a, fp64_fpxx) + NEXT(fpxx, fp64a_fp64) + NEXT(fp64, fp64a_fpxx) + END_STATE + + START_STATE(fp64a_fp64_fpxxo) + NEXT(fp64a, fp64_fpxxo) + NEXT(fpxxo, fp64a_fp64) + NEXT(fp64, fp64a_fpxxo) + END_STATE + + START_STATE(fp64a_fp64_fpxxo_fpxx) + NEXT(fp64a, fp64_fpxx_fpxxo) + NEXT(fpxx, fp64a_fp64_fpxxo) + NEXT(fpxxo, fp64a_fp64_fpxx) + NEXT(fp64, fp64a_fpxx_fpxxo) + END_STATE + + START_STATE(fp32_fp64a_fpxx) + NEXT(fp32, fp64a_fpxx) + NEXT(fp64a, fp32_fpxx) + NEXT(fpxx, fp64a_fp32) + END_STATE + + START_STATE(fp32_fp64a_fpxxo) + NEXT(fp32, fp64a_fpxxo) + NEXT(fp64a, fp32_fpxxo) + NEXT(fpxxo, fp64a_fp32) + END_STATE + + START_STATE(fp32_fp64a_fpxxo_fpxx) + NEXT(fp32, fp64a_fpxx_fpxxo) + NEXT(fp64a, fp32_fpxxo_fpxx) + NEXT(fpxx, fp32_fp64a_fpxxo) + NEXT(fpxxo, fp32_fp64a_fpxx) + END_STATE + } + + return true; +} + +static int +mode_transition_valid_p (void) +{ + int prev_fp_mode; + + /* Get the current fp mode. */ + prev_fp_mode = current_fp_mode; +#if HAVE_PRCTL_FP_MODE + current_fp_mode = prctl (PR_GET_FP_MODE); + + /* If the prctl call fails assume the core only has FR0 mode support. */ + if (current_fp_mode == -1) + current_fp_mode = 0; +#endif + + if (!current_mode_valid_p (current_fp_state)) + return 0; + + /* Check if mode changes are not allowed but a mode change happened. */ + if (cant_change_mode + && current_fp_mode != prev_fp_mode) + return 0; + + return 1; +} + +/* Load OBJ and check that it was/was not loaded correctly. */ +bool +load_object (enum fp_obj obj) +{ + bool should_load = set_next_fp_state (obj); + + shared_lib_ptrs[obj] = dlopen (shared_lib_names[obj], RTLD_LAZY); + + /* If we expected an error and the load was successful then fail. */ + if (!should_load && (shared_lib_ptrs[obj] != 0)) + return false; + + if (should_load && (shared_lib_ptrs[obj] == 0)) + return false; + + if (!mode_transition_valid_p ()) + return false; + + return true; +} + +/* Remove an object and check the state remains valid. */ +bool +unload_object (enum fp_obj obj) +{ + if (!shared_lib_ptrs[obj]) + return true; + + remove_object (obj); + + if (dlclose (shared_lib_ptrs[obj]) != 0) + return false; + + shared_lib_ptrs[obj] = 0; + + if (!mode_transition_valid_p ()) + return false; + + return true; +} + +/* Load every permuation of OBJECTS. */ +static bool +test_permutations (enum fp_obj objects[], int count) +{ + int i; + + for (i = 0 ; i < count ; i++) + { + if (!load_object (objects[i])) + return false; + + if (count > 1) + { + enum fp_obj new_objects[count - 1]; + int j; + int k = 0; + + for (j = 0 ; j < count ; j++) + { + if (j != i) + new_objects[k++] = objects[j]; + } + + if (!test_permutations (new_objects, count - 1)) + return false; + } + + if (!unload_object (objects[i])) + return false; + } + return true; +} + +int +do_test (void) +{ +#if HAVE_PRCTL_FP_MODE + /* Determine available hardware support and current mode. */ + current_fp_mode = prctl (PR_GET_FP_MODE); + + /* If the prctl call fails assume the core only has FR0 mode support. */ + if (current_fp_mode == -1) + current_fp_mode = 0; + else + { + if (prctl (PR_SET_FP_MODE, 0) != 0) + { + if (errno == ENOTSUP) + is_r6 = true; + else + { + printf ("unexpected error from PR_SET_FP_MODE, 0: %m\n"); + return 1; + } + } + + if (prctl (PR_SET_FP_MODE, PR_FP_MODE_FR) != 0) + { + if (errno != ENOTSUP) + { + printf ("unexpected error from PR_SET_FP_MODE, " + "PR_FP_MODE_FR: %m\n"); + return 1; + } + } + else + has_fr1 = true; + + if (prctl (PR_SET_FP_MODE, PR_FP_MODE_FR | PR_FP_MODE_FRE) != 0) + { + if (errno != ENOTSUP) + { + printf ("unexpected error from PR_SET_FP_MODE, " + "PR_FP_MODE_FR | PR_FP_MODE_FRE: %m\n"); + return 1; + } + } + else + has_fre = true; + + if (prctl (PR_SET_FP_MODE, current_fp_mode) != 0) + { + printf ("unable to restore initial FP mode: %m\n"); + return 1; + } + } + + if ((is_r6 && !(current_fp_mode & PR_FP_MODE_FR)) + || (!has_fr1 && (current_fp_mode & PR_FP_MODE_FR)) + || (!has_fre && (current_fp_mode & PR_FP_MODE_FRE))) + { + puts ("Inconsistency detected between initial FP mode " + "and supported FP modes\n"); + return 1; + } +#else + current_fp_mode = 0; +#endif + + /* Set up the initial state from executable and LDSO. Assumptions: + 1) All system libraries have the same ABI as ld.so. + 2) Due to the fact that ld.so is tested by invoking it directly + rather than via an interpreter, there is no point in varying + the ABI of the test program. Instead the ABI only varies for + the shared libraries which get loaded. */ + if (!set_next_fp_state (FPABI_NATIVE)) + { + puts ("Unable to enter initial ABI state\n"); + return 1; + } + + /* Compare the computed state with the hardware state. */ + if (!mode_transition_valid_p ()) + return 1; + + /* Run all possible test permutations. */ + if (!test_permutations (test_objects, FPABI_COUNT)) + { + puts ("Mode checks failed\n"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../../test-skeleton.c" diff --git a/REORG.TODO/sysdeps/mips/tst-audit.h b/REORG.TODO/sysdeps/mips/tst-audit.h new file mode 100644 index 0000000000..c9c6ddb079 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/tst-audit.h @@ -0,0 +1,39 @@ +/* Definitions for testing PLT entry/exit auditing. ARM version. + + Copyright (C) 2005-2017 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/>. */ + +#include <sgidefs.h> + +#if _MIPS_SIM == _ABIO32 +#define pltenter la_mips_o32_gnu_pltenter +#define pltexit la_mips_o32_gnu_pltexit +#define La_regs La_mips_32_regs +#define La_retval La_mips_32_retval +#else +#if _MIPS_SIM == _ABIN32 +#define pltenter la_mips_n32_gnu_pltenter +#define pltexit la_mips_n32_gnu_pltexit +#else +#define pltenter la_mips_n64_gnu_pltenter +#define pltexit la_mips_n64_gnu_pltexit +#endif +#define La_regs La_mips_64_regs +#define La_retval La_mips_64_retval +#endif +#define int_retval lrv_v0 diff --git a/REORG.TODO/sysdeps/mips/tst-mode-switch-1.c b/REORG.TODO/sysdeps/mips/tst-mode-switch-1.c new file mode 100644 index 0000000000..cdfa5aa859 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/tst-mode-switch-1.c @@ -0,0 +1,126 @@ +/* Copyright (C) 2014-2017 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/>. */ + +#include <errno.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> +#include <sys/prctl.h> + +#if __mips_fpr != 0 || _MIPS_SPFPSET != 16 +# error This test requires -mfpxx -mno-odd-spreg +#endif + +/* This test verifies that mode changes do not clobber register state + in other threads. */ + +static volatile int finished; +static int mode[6] = + { + 0, + PR_FP_MODE_FR, + PR_FP_MODE_FR | PR_FP_MODE_FRE, + PR_FP_MODE_FR, + 0, + PR_FP_MODE_FR | PR_FP_MODE_FRE + }; + +static void * +thread_function (void * arg __attribute__ ((unused))) +{ + volatile int i = 0; + volatile float f = 0.0; + volatile double d = 0.0; + + while (!finished) + { + if ((float) i != f || (double) i != d) + { + printf ("unexpected value: i(%d) f(%f) d(%f)\n", i, f, d); + exit (1); + } + + if (i == 100) + { + i = 0; + f = 0.0; + d = 0.0; + } + + i++; + f++; + d++; + } + return NULL; +} + +static int +do_test (void) +{ + int count = sysconf (_SC_NPROCESSORS_ONLN); + if (count <= 0) + count = 1; + count *= 4; + + pthread_t th[count]; + int i; + int result = 0; + + for (i = 0; i < count; ++i) + if (pthread_create (&th[i], NULL, thread_function, 0) != 0) + { + printf ("creation of thread %d failed\n", i); + exit (1); + } + + for (i = 0 ; i < 1000000 ; i++) + { + if (prctl (PR_SET_FP_MODE, mode[i % 6]) != 0 + && errno != ENOTSUP) + { + printf ("prctl PR_SET_FP_MODE failed: %m\n"); + exit (1); + } + } + + finished = 1; + + for (i = 0; i < count; ++i) + { + void *v; + if (pthread_join (th[i], &v) != 0) + { + printf ("join of thread %d failed\n", i); + result = 1; + } + else if (v != NULL) + { + printf ("join %d successful, but child failed\n", i); + result = 1; + } + else + printf ("join %d successful\n", i); + } + + return result; +} + +#define TEST_FUNCTION do_test () +#include "../../test-skeleton.c" diff --git a/REORG.TODO/sysdeps/mips/tst-mode-switch-2.c b/REORG.TODO/sysdeps/mips/tst-mode-switch-2.c new file mode 100644 index 0000000000..6fd1e914a9 --- /dev/null +++ b/REORG.TODO/sysdeps/mips/tst-mode-switch-2.c @@ -0,0 +1,166 @@ +/* Copyright (C) 2014-2017 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/>. */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> +#include <pthread.h> +#include <sys/prctl.h> + +#if __mips_fpr != 0 || _MIPS_SPFPSET != 16 +# error This test requires -mfpxx -mno-odd-spreg +#endif + +/* This test verifies that all threads in a process see a mode + change when any thread causes a mode change. */ + +static int mode[6] = + { + 0, + PR_FP_MODE_FR, + PR_FP_MODE_FR | PR_FP_MODE_FRE, + PR_FP_MODE_FR, + 0, + PR_FP_MODE_FR | PR_FP_MODE_FRE + }; +static volatile int current_mode; +static volatile int finished; +static pthread_barrier_t barr_ready; +static pthread_barrier_t barr_cont; + +static void * +thread_function (void * arg __attribute__ ((unused))) +{ + while (!finished) + { + int res = pthread_barrier_wait (&barr_ready); + + if (res != 0 && res != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("barrier wait failed: %m\n"); + exit (1); + } + + int mode = prctl (PR_GET_FP_MODE); + + if (mode != current_mode) + { + printf ("unexpected mode: %d != %d\n", mode, current_mode); + exit (1); + } + + res = pthread_barrier_wait (&barr_cont); + + if (res != 0 && res != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("barrier wait failed: %m\n"); + exit (1); + } + } + return NULL; +} + +static int +do_test (void) +{ + int count = sysconf (_SC_NPROCESSORS_ONLN); + if (count <= 0) + count = 1; + count *= 4; + + pthread_t th[count]; + int i; + int result = 0; + + if (pthread_barrier_init (&barr_ready, NULL, count + 1) != 0) + { + printf ("failed to initialize barrier: %m\n"); + exit (1); + } + + if (pthread_barrier_init (&barr_cont, NULL, count + 1) != 0) + { + printf ("failed to initialize barrier: %m\n"); + exit (1); + } + + for (i = 0; i < count; ++i) + if (pthread_create (&th[i], NULL, thread_function, 0) != 0) + { + printf ("creation of thread %d failed\n", i); + exit (1); + } + + for (i = 0 ; i < 7 ; i++) + { + if (prctl (PR_SET_FP_MODE, mode[i % 6]) != 0) + { + if (errno != ENOTSUP) + { + printf ("prctl PR_SET_FP_MODE failed: %m"); + exit (1); + } + } + else + current_mode = mode[i % 6]; + + + int res = pthread_barrier_wait (&barr_ready); + + if (res != 0 && res != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("barrier wait failed: %m\n"); + exit (1); + } + + if (i == 6) + finished = 1; + + res = pthread_barrier_wait (&barr_cont); + + if (res != 0 && res != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("barrier wait failed: %m\n"); + exit (1); + } + } + + for (i = 0; i < count; ++i) + { + void *v; + if (pthread_join (th[i], &v) != 0) + { + printf ("join of thread %d failed\n", i); + result = 1; + } + else if (v != NULL) + { + printf ("join %d successful, but child failed\n", i); + result = 1; + } + else + printf ("join %d successful\n", i); + } + + return result; +} + +#define TEST_FUNCTION do_test () +#include "../../test-skeleton.c" diff --git a/REORG.TODO/sysdeps/mips/tst-mode-switch-3.c b/REORG.TODO/sysdeps/mips/tst-mode-switch-3.c new file mode 100644 index 0000000000..405eacdf5a --- /dev/null +++ b/REORG.TODO/sysdeps/mips/tst-mode-switch-3.c @@ -0,0 +1,93 @@ +/* Copyright (C) 2014-2017 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/>. */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <setjmp.h> +#include <sys/prctl.h> + +#if __mips_fpr != 0 || _MIPS_SPFPSET != 16 +# error This test requires -mfpxx -mno-odd-spreg +#endif + +/* This test verifies that mode changes between a setjmp and longjmp do + not corrupt the state of callee-saved registers. */ + +static int mode[6] = + { + 0, + PR_FP_MODE_FR, + PR_FP_MODE_FR | PR_FP_MODE_FRE, + PR_FP_MODE_FR, + 0, + PR_FP_MODE_FR | PR_FP_MODE_FRE + }; +static jmp_buf env; +float check1 = 2.0; +double check2 = 3.0; + +static int +do_test (void) +{ + int i; + int result = 0; + + for (i = 0 ; i < 7 ; i++) + { + int retval; + register float test1 __asm ("$f20"); + register double test2 __asm ("$f22"); + + /* Hide what we are doing to $f20 and $f22 from the compiler. */ + __asm __volatile ("l.s %0,%2\n" + "l.d %1,%3\n" + : "=f" (test1), "=f" (test2) + : "m" (check1), "m" (check2)); + + retval = setjmp (env); + + /* Make sure the compiler knows we want to access the variables + via the named registers again. */ + __asm __volatile ("" : : "f" (test1), "f" (test2)); + + if (test1 != check1 || test2 != check2) + { + printf ("Corrupt register detected: $20 %f = %f, $22 %f = %f\n", + test1, check1, test2, check2); + result = 1; + } + + if (retval == 0) + { + if (prctl (PR_SET_FP_MODE, mode[i % 6]) != 0 + && errno != ENOTSUP) + { + printf ("prctl PR_SET_FP_MODE failed: %m"); + exit (1); + } + longjmp (env, 0); + } + } + + return result; +} + +#define TEST_FUNCTION do_test () +#include "../../test-skeleton.c" |