diff options
Diffstat (limited to 'REORG.TODO/sysdeps/sparc/sparc32')
214 files changed, 12270 insertions, 0 deletions
diff --git a/REORG.TODO/sysdeps/sparc/sparc32/Implies b/REORG.TODO/sysdeps/sparc/sparc32/Implies new file mode 100644 index 0000000000..436436a651 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/Implies @@ -0,0 +1,6 @@ +wordsize-32 +# SPARC uses IEEE 754 floating point. +ieee754/ldbl-128 +ieee754/dbl-64 +ieee754/flt-32 +sparc/sparc32/soft-fp diff --git a/REORG.TODO/sysdeps/sparc/sparc32/Makefile b/REORG.TODO/sysdeps/sparc/sparc32/Makefile new file mode 100644 index 0000000000..14d6e03c6f --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/Makefile @@ -0,0 +1,55 @@ +# 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/>. + +ifeq ($(subdir),gnulib) +sysdep_routines = dotmul umul $(divrem) alloca +endif # gnulib + +# We distribute these files, even though they are generated, +# so as to avoid the need for a functioning m4 to build the library. +divrem := sdiv udiv rem urem + ++divrem-NAME-sdiv := div ++divrem-NAME-udiv := udiv ++divrem-NAME-rem := rem ++divrem-NAME-urem := urem ++divrem-NAME = $(+divrem-NAME-$(basename $(notdir $@))) ++divrem-OP-div := div ++divrem-OP-udiv := div ++divrem-OP-rem := rem ++divrem-OP-urem := rem ++divrem-S-div := true ++divrem-S-rem := true ++divrem-S-udiv := false ++divrem-S-urem := false +$(divrem:%=$(sysdep_dir)/sparc/sparc32/%.S): $(sysdep_dir)/sparc/sparc32/divrem.m4 + (echo "define(NAME,\`.$(+divrem-NAME)')\ + define(OP,\`$(+divrem-OP-$(+divrem-NAME))')\ + define(S,\`$(+divrem-S-$(+divrem-NAME))')\ + /* This file is generated from divrem.m4; DO NOT EDIT! */"; \ + cat $<) | $(M4) > $@-tmp +# Make it unwritable so noone will edit it by mistake. + -chmod a-w $@-tmp + mv -f $@-tmp $@ + +sysdep-realclean := $(sysdep-realclean) $(divrem:%=sysdeps/sparc/sparc32/%.S) + +# libgcc __divdi3 and __moddi3 uses .udiv and since it is also exported by +# libc.so linker will create PLTs for the symbol. To avoid it we strong alias +# the exported libc one to __wrap_.udiv and use linker option --wrap to make any +# call to .udiv to call the wrapper symbol. +libc.so-gnulib += -Wl,--wrap=.udiv diff --git a/REORG.TODO/sysdeps/sparc/sparc32/Versions b/REORG.TODO/sysdeps/sparc/sparc32/Versions new file mode 100644 index 0000000000..6d3bfe880e --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/Versions @@ -0,0 +1,10 @@ +libc { + GLIBC_2.0 { + .div; .mul; .rem; .udiv; .umul; .urem; + } +} +libm { + GLIBC_2.23 { + __sqrtl_finite; + } +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/__longjmp.S b/REORG.TODO/sysdeps/sparc/sparc32/__longjmp.S new file mode 100644 index 0000000000..2cfb6c23e7 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/__longjmp.S @@ -0,0 +1,93 @@ +/* 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/>. */ + +#include <sysdep.h> + +#include <jmpbuf-offsets.h> +#define ENV(base,reg) [%base + (reg * 4)] +#define ST_FLUSH_WINDOWS 3 + +ENTRY(__longjmp) + /* Store our arguments in global registers so we can still + use them while unwinding frames and their register windows. */ + + ld ENV(o0,JB_FP), %g3 /* Cache target FP in register %g3. */ +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (%g3, %g3, %g4) +#endif + mov %o0, %g1 /* ENV in %g1 */ + orcc %o1, %g0, %g2 /* VAL in %g2 */ + be,a 0f /* Branch if zero; else skip delay slot. */ + mov 1, %g2 /* Delay slot only hit if zero: VAL = 1. */ +0: + xor %fp, %g3, %o0 + add %fp, 512, %o1 + andncc %o0, 4095, %o0 + bne LOC(thread) + cmp %o1, %g3 + bl LOC(thread) + + /* Now we will loop, unwinding the register windows up the stack + until the restored %fp value matches the target value in %g3. */ + +LOC(loop): + cmp %fp, %g3 /* Have we reached the target frame? */ + bl,a LOC(loop) /* Loop while current fp is below target. */ + restore /* Unwind register window in delay slot. */ + be,a LOC(found) /* Better have hit it exactly. */ + ld ENV(g1,JB_SP), %o0 /* Delay slot: extract target SP. */ + +LOC(thread): + save %sp, -96, %sp + /* + * Do a "flush register windows trap". The trap handler in the + * kernel writes all the register windows to their stack slots, and + * marks them all as invalid (needing to be sucked up from the + * stack when used). This ensures that all information needed to + * unwind to these callers is in memory, not in the register + * windows. + */ + ta ST_FLUSH_WINDOWS +#ifdef PTR_DEMANGLE + ld ENV(g1,JB_PC), %g5 /* Set return PC. */ + ld ENV(g1,JB_SP), %g1 /* Set saved SP on restore below. */ + PTR_DEMANGLE2 (%i7, %g5, %g4) + PTR_DEMANGLE2 (%fp, %g1, %g4) +#else + ld ENV(g1,JB_PC), %i7 /* Set return PC. */ + ld ENV(g1,JB_SP), %fp /* Set saved SP on restore below. */ +#endif + jmp %i7 + 8 + restore %g2, 0, %o0 /* Restore values from above register frame. */ + +LOC(found): + /* We have unwound register windows so %fp matches the target. */ +#ifdef PTR_DEMANGLE + PTR_DEMANGLE2 (%sp, %o0, %g4) +#else + mov %o0, %sp /* OK, install new SP. */ +#endif + +LOC(sp_ok): + ld ENV(g1,JB_PC), %o0 /* Extract target return PC. */ +#ifdef PTR_DEMANGLE + PTR_DEMANGLE2 (%o0, %o0, %g4) +#endif + jmp %o0 + 8 /* Return there. */ + mov %g2, %o0 /* Delay slot: set return value. */ + +END(__longjmp) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/add_n.S b/REORG.TODO/sysdeps/sparc/sparc32/add_n.S new file mode 100644 index 0000000000..75289af5f9 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/add_n.S @@ -0,0 +1,237 @@ +! SPARC __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; see the file COPYING.LIB. If not, +! see <http://www.gnu.org/licenses/>. + + +! INPUT PARAMETERS +#define RES_PTR %o0 +#define S1_PTR %o1 +#define S2_PTR %o2 +#define SIZE %o3 + +#include <sysdep.h> + +ENTRY(__mpn_add_n) + xor S2_PTR,RES_PTR,%g1 + andcc %g1,4,%g0 + bne LOC(1) ! branch if alignment differs + nop +! ** V1a ** +LOC(0): andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0 + be LOC(v1) ! if no, branch + nop +/* Add least significant limb separately to align RES_PTR and S2_PTR */ + ld [S1_PTR],%g4 + add S1_PTR,4,S1_PTR + ld [S2_PTR],%g2 + add S2_PTR,4,S2_PTR + add SIZE,-1,SIZE + addcc %g4,%g2,%o4 + st %o4,[RES_PTR] + add RES_PTR,4,RES_PTR +LOC(v1): + addx %g0,%g0,%o4 ! save cy in register + cmp SIZE,2 ! if SIZE < 2 ... + bl LOC(end2) ! ... branch to tail code + subcc %g0,%o4,%g0 ! restore cy + + ld [S1_PTR+0],%g4 + addcc SIZE,-10,SIZE + ld [S1_PTR+4],%g1 + ldd [S2_PTR+0],%g2 + blt LOC(fin1) + subcc %g0,%o4,%g0 ! restore cy +/* Add blocks of 8 limbs until less than 8 limbs remain */ +LOC(loop1): + addxcc %g4,%g2,%o4 + ld [S1_PTR+8],%g4 + addxcc %g1,%g3,%o5 + ld [S1_PTR+12],%g1 + ldd [S2_PTR+8],%g2 + std %o4,[RES_PTR+0] + addxcc %g4,%g2,%o4 + ld [S1_PTR+16],%g4 + addxcc %g1,%g3,%o5 + ld [S1_PTR+20],%g1 + ldd [S2_PTR+16],%g2 + std %o4,[RES_PTR+8] + addxcc %g4,%g2,%o4 + ld [S1_PTR+24],%g4 + addxcc %g1,%g3,%o5 + ld [S1_PTR+28],%g1 + ldd [S2_PTR+24],%g2 + std %o4,[RES_PTR+16] + addxcc %g4,%g2,%o4 + ld [S1_PTR+32],%g4 + addxcc %g1,%g3,%o5 + ld [S1_PTR+36],%g1 + ldd [S2_PTR+32],%g2 + std %o4,[RES_PTR+24] + addx %g0,%g0,%o4 ! save cy in register + addcc SIZE,-8,SIZE + add S1_PTR,32,S1_PTR + add S2_PTR,32,S2_PTR + add RES_PTR,32,RES_PTR + bge LOC(loop1) + subcc %g0,%o4,%g0 ! restore cy + +LOC(fin1): + addcc SIZE,8-2,SIZE + blt LOC(end1) + subcc %g0,%o4,%g0 ! restore cy +/* Add blocks of 2 limbs until less than 2 limbs remain */ +LOC(loope1): + addxcc %g4,%g2,%o4 + ld [S1_PTR+8],%g4 + addxcc %g1,%g3,%o5 + ld [S1_PTR+12],%g1 + ldd [S2_PTR+8],%g2 + std %o4,[RES_PTR+0] + addx %g0,%g0,%o4 ! save cy in register + addcc SIZE,-2,SIZE + add S1_PTR,8,S1_PTR + add S2_PTR,8,S2_PTR + add RES_PTR,8,RES_PTR + bge LOC(loope1) + subcc %g0,%o4,%g0 ! restore cy +LOC(end1): + addxcc %g4,%g2,%o4 + addxcc %g1,%g3,%o5 + std %o4,[RES_PTR+0] + addx %g0,%g0,%o4 ! save cy in register + + andcc SIZE,1,%g0 + be LOC(ret1) + subcc %g0,%o4,%g0 ! restore cy +/* Add last limb */ + ld [S1_PTR+8],%g4 + ld [S2_PTR+8],%g2 + addxcc %g4,%g2,%o4 + st %o4,[RES_PTR+8] + +LOC(ret1): + retl + addx %g0,%g0,%o0 ! return carry-out from most sign. limb + +LOC(1): xor S1_PTR,RES_PTR,%g1 + andcc %g1,4,%g0 + bne LOC(2) + nop +! ** V1b ** + mov S2_PTR,%g1 + mov S1_PTR,S2_PTR + b LOC(0) + mov %g1,S1_PTR + +! ** V2 ** +/* If we come here, the alignment of S1_PTR and RES_PTR as well as the + alignment of S2_PTR and RES_PTR differ. Since there are only two ways + things can be aligned (that we care about) we now know that the alignment + of S1_PTR and S2_PTR are the same. */ + +LOC(2): cmp SIZE,1 + be LOC(jone) + nop + andcc S1_PTR,4,%g0 ! S1_PTR unaligned? Side effect: cy=0 + be LOC(v2) ! if no, branch + nop +/* Add least significant limb separately to align S1_PTR and S2_PTR */ + ld [S1_PTR],%g4 + add S1_PTR,4,S1_PTR + ld [S2_PTR],%g2 + add S2_PTR,4,S2_PTR + add SIZE,-1,SIZE + addcc %g4,%g2,%o4 + st %o4,[RES_PTR] + add RES_PTR,4,RES_PTR + +LOC(v2): + addx %g0,%g0,%o4 ! save cy in register + addcc SIZE,-8,SIZE + blt LOC(fin2) + subcc %g0,%o4,%g0 ! restore cy +/* Add blocks of 8 limbs until less than 8 limbs remain */ +LOC(loop2): + ldd [S1_PTR+0],%g2 + ldd [S2_PTR+0],%o4 + addxcc %g2,%o4,%g2 + st %g2,[RES_PTR+0] + addxcc %g3,%o5,%g3 + st %g3,[RES_PTR+4] + ldd [S1_PTR+8],%g2 + ldd [S2_PTR+8],%o4 + addxcc %g2,%o4,%g2 + st %g2,[RES_PTR+8] + addxcc %g3,%o5,%g3 + st %g3,[RES_PTR+12] + ldd [S1_PTR+16],%g2 + ldd [S2_PTR+16],%o4 + addxcc %g2,%o4,%g2 + st %g2,[RES_PTR+16] + addxcc %g3,%o5,%g3 + st %g3,[RES_PTR+20] + ldd [S1_PTR+24],%g2 + ldd [S2_PTR+24],%o4 + addxcc %g2,%o4,%g2 + st %g2,[RES_PTR+24] + addxcc %g3,%o5,%g3 + st %g3,[RES_PTR+28] + addx %g0,%g0,%o4 ! save cy in register + addcc SIZE,-8,SIZE + add S1_PTR,32,S1_PTR + add S2_PTR,32,S2_PTR + add RES_PTR,32,RES_PTR + bge LOC(loop2) + subcc %g0,%o4,%g0 ! restore cy + +LOC(fin2): + addcc SIZE,8-2,SIZE + blt LOC(end2) + subcc %g0,%o4,%g0 ! restore cy +LOC(loope2): + ldd [S1_PTR+0],%g2 + ldd [S2_PTR+0],%o4 + addxcc %g2,%o4,%g2 + st %g2,[RES_PTR+0] + addxcc %g3,%o5,%g3 + st %g3,[RES_PTR+4] + addx %g0,%g0,%o4 ! save cy in register + addcc SIZE,-2,SIZE + add S1_PTR,8,S1_PTR + add S2_PTR,8,S2_PTR + add RES_PTR,8,RES_PTR + bge LOC(loope2) + subcc %g0,%o4,%g0 ! restore cy +LOC(end2): + andcc SIZE,1,%g0 + be LOC(ret2) + subcc %g0,%o4,%g0 ! restore cy +/* Add last limb */ +LOC(jone): + ld [S1_PTR],%g4 + ld [S2_PTR],%g2 + addxcc %g4,%g2,%o4 + st %o4,[RES_PTR] + +LOC(ret2): + retl + addx %g0,%g0,%o0 ! return carry-out from most sign. limb + +END(__mpn_add_n) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/addmul_1.S b/REORG.TODO/sysdeps/sparc/sparc32/addmul_1.S new file mode 100644 index 0000000000..080e5f3d06 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/addmul_1.S @@ -0,0 +1,146 @@ +! SPARC __mpn_addmul_1 -- Multiply a limb vector with a limb and add +! the result 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; see the file COPYING.LIB. If not, +! see <http://www.gnu.org/licenses/>. + + +! INPUT PARAMETERS +! RES_PTR o0 +! S1_PTR o1 +! SIZE o2 +! S2_LIMB o3 + +#include <sysdep.h> + +ENTRY(__mpn_addmul_1) + ! Make S1_PTR and RES_PTR point at the end of their blocks + ! and put (- 4 x SIZE) in index/loop counter. + sll %o2,2,%o2 + add %o0,%o2,%o4 ! RES_PTR in o4 since o0 is retval + add %o1,%o2,%o1 + sub %g0,%o2,%o2 + + cmp %o3,0xfff + bgu LOC(large) + nop + + ld [%o1+%o2],%o5 + mov 0,%o0 + b LOC(0) + add %o4,-4,%o4 +LOC(loop0): + addcc %o5,%g1,%g1 + ld [%o1+%o2],%o5 + addx %o0,%g0,%o0 + st %g1,[%o4+%o2] +LOC(0): wr %g0,%o3,%y + sra %o5,31,%g2 + and %o3,%g2,%g2 + andcc %g1,0,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,0,%g1 + sra %g1,20,%g4 + sll %g1,12,%g1 + rd %y,%g3 + srl %g3,20,%g3 + or %g1,%g3,%g1 + + addcc %g1,%o0,%g1 + addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb + addcc %o2,4,%o2 ! loop counter + bne LOC(loop0) + ld [%o4+%o2],%o5 + + addcc %o5,%g1,%g1 + addx %o0,%g0,%o0 + retl + st %g1,[%o4+%o2] + + +LOC(large): + ld [%o1+%o2],%o5 + mov 0,%o0 + sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0 + b LOC(1) + add %o4,-4,%o4 +LOC(loop): + addcc %o5,%g3,%g3 + ld [%o1+%o2],%o5 + addx %o0,%g0,%o0 + st %g3,[%o4+%o2] +LOC(1): wr %g0,%o5,%y + and %o5,%g4,%g2 + andcc %g0,%g0,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%g0,%g1 + rd %y,%g3 + addcc %g3,%o0,%g3 + addx %g2,%g1,%o0 + addcc %o2,4,%o2 + bne LOC(loop) + ld [%o4+%o2],%o5 + + addcc %o5,%g3,%g3 + addx %o0,%g0,%o0 + retl + st %g3,[%o4+%o2] + +END(__mpn_addmul_1) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/alloca.S b/REORG.TODO/sysdeps/sparc/sparc32/alloca.S new file mode 100644 index 0000000000..60cd800800 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/alloca.S @@ -0,0 +1,28 @@ +/* Copyright (C) 1994-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> + +/* Code produced by Sun's C compiler calls this function with two extra + arguments which it makes relocatable symbols but seem always to be + the constant 96; I have no idea what they are for. */ + +ENTRY (__builtin_alloca) + sub %sp, %o0, %sp /* Push some stack space. */ + retl /* Return; the returned buffer leaves 96 */ + add %sp, 96, %o0 /* bytes of register save area at the top. */ +END (__builtin_alloca) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/atomic-machine.h b/REORG.TODO/sysdeps/sparc/sparc32/atomic-machine.h new file mode 100644 index 0000000000..a2fe8485b4 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/atomic-machine.h @@ -0,0 +1,363 @@ +/* Atomic operations. sparc32 version. + Copyright (C) 2003-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _ATOMIC_MACHINE_H +#define _ATOMIC_MACHINE_H 1 + +#include <stdint.h> + +typedef int8_t atomic8_t; +typedef uint8_t uatomic8_t; +typedef int_fast8_t atomic_fast8_t; +typedef uint_fast8_t uatomic_fast8_t; + +typedef int16_t atomic16_t; +typedef uint16_t uatomic16_t; +typedef int_fast16_t atomic_fast16_t; +typedef uint_fast16_t uatomic_fast16_t; + +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; + +#define __HAVE_64B_ATOMICS 0 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + +/* XXX Is this actually correct? */ +#define ATOMIC_EXCHANGE_USES_CAS 1 + + +/* We have no compare and swap, just test and set. + The following implementation contends on 64 global locks + per library and assumes no variable will be accessed using atomic.h + macros from two different libraries. */ + +__make_section_unallocated + (".gnu.linkonce.b.__sparc32_atomic_locks, \"aw\", %nobits"); + +volatile unsigned char __sparc32_atomic_locks[64] + __attribute__ ((nocommon, section (".gnu.linkonce.b.__sparc32_atomic_locks" + __sec_comment), + visibility ("hidden"))); + +#define __sparc32_atomic_do_lock(addr) \ + do \ + { \ + unsigned int __old_lock; \ + unsigned int __idx = (((long) addr >> 2) ^ ((long) addr >> 12)) \ + & 63; \ + do \ + __asm __volatile ("ldstub %1, %0" \ + : "=r" (__old_lock), \ + "=m" (__sparc32_atomic_locks[__idx]) \ + : "m" (__sparc32_atomic_locks[__idx]) \ + : "memory"); \ + while (__old_lock); \ + } \ + while (0) + +#define __sparc32_atomic_do_unlock(addr) \ + do \ + { \ + __sparc32_atomic_locks[(((long) addr >> 2) \ + ^ ((long) addr >> 12)) & 63] = 0; \ + __asm __volatile ("" ::: "memory"); \ + } \ + while (0) + +#define __sparc32_atomic_do_lock24(addr) \ + do \ + { \ + unsigned int __old_lock; \ + do \ + __asm __volatile ("ldstub %1, %0" \ + : "=r" (__old_lock), "=m" (*(addr)) \ + : "m" (*(addr)) \ + : "memory"); \ + while (__old_lock); \ + } \ + while (0) + +#define __sparc32_atomic_do_unlock24(addr) \ + do \ + { \ + __asm __volatile ("" ::: "memory"); \ + *(char *) (addr) = 0; \ + } \ + while (0) + + +#ifndef SHARED +# define __v9_compare_and_exchange_val_32_acq(mem, newval, oldval) \ +({union { __typeof (oldval) a; uint32_t v; } oldval_arg = { .a = (oldval) }; \ + union { __typeof (newval) a; uint32_t v; } newval_arg = { .a = (newval) }; \ + register uint32_t __acev_tmp __asm ("%g6"); \ + register __typeof (mem) __acev_mem __asm ("%g1") = (mem); \ + register uint32_t __acev_oldval __asm ("%g5"); \ + __acev_tmp = newval_arg.v; \ + __acev_oldval = oldval_arg.v; \ + /* .word 0xcde05005 is cas [%g1], %g5, %g6. Can't use cas here though, \ + because as will then mark the object file as V8+ arch. */ \ + __asm __volatile (".word 0xcde05005" \ + : "+r" (__acev_tmp), "=m" (*__acev_mem) \ + : "r" (__acev_oldval), "m" (*__acev_mem), \ + "r" (__acev_mem) : "memory"); \ + (__typeof (oldval)) __acev_tmp; }) +#endif + +/* The only basic operation needed is compare and exchange. */ +#define __v7_compare_and_exchange_val_acq(mem, newval, oldval) \ + ({ __typeof (mem) __acev_memp = (mem); \ + __typeof (*mem) __acev_ret; \ + __typeof (*mem) __acev_newval = (newval); \ + \ + __sparc32_atomic_do_lock (__acev_memp); \ + __acev_ret = *__acev_memp; \ + if (__acev_ret == (oldval)) \ + *__acev_memp = __acev_newval; \ + __sparc32_atomic_do_unlock (__acev_memp); \ + __acev_ret; }) + +#define __v7_compare_and_exchange_bool_acq(mem, newval, oldval) \ + ({ __typeof (mem) __aceb_memp = (mem); \ + int __aceb_ret; \ + __typeof (*mem) __aceb_newval = (newval); \ + \ + __sparc32_atomic_do_lock (__aceb_memp); \ + __aceb_ret = 0; \ + if (*__aceb_memp == (oldval)) \ + *__aceb_memp = __aceb_newval; \ + else \ + __aceb_ret = 1; \ + __sparc32_atomic_do_unlock (__aceb_memp); \ + __aceb_ret; }) + +#define __v7_exchange_acq(mem, newval) \ + ({ __typeof (mem) __acev_memp = (mem); \ + __typeof (*mem) __acev_ret; \ + __typeof (*mem) __acev_newval = (newval); \ + \ + __sparc32_atomic_do_lock (__acev_memp); \ + __acev_ret = *__acev_memp; \ + *__acev_memp = __acev_newval; \ + __sparc32_atomic_do_unlock (__acev_memp); \ + __acev_ret; }) + +#define __v7_exchange_and_add(mem, value) \ + ({ __typeof (mem) __acev_memp = (mem); \ + __typeof (*mem) __acev_ret; \ + \ + __sparc32_atomic_do_lock (__acev_memp); \ + __acev_ret = *__acev_memp; \ + *__acev_memp = __acev_ret + (value); \ + __sparc32_atomic_do_unlock (__acev_memp); \ + __acev_ret; }) + +/* Special versions, which guarantee that top 8 bits of all values + are cleared and use those bits as the ldstub lock. */ +#define __v7_compare_and_exchange_val_24_acq(mem, newval, oldval) \ + ({ __typeof (mem) __acev_memp = (mem); \ + __typeof (*mem) __acev_ret; \ + __typeof (*mem) __acev_newval = (newval); \ + \ + __sparc32_atomic_do_lock24 (__acev_memp); \ + __acev_ret = *__acev_memp & 0xffffff; \ + if (__acev_ret == (oldval)) \ + *__acev_memp = __acev_newval; \ + else \ + __sparc32_atomic_do_unlock24 (__acev_memp); \ + __asm __volatile ("" ::: "memory"); \ + __acev_ret; }) + +#define __v7_exchange_24_rel(mem, newval) \ + ({ __typeof (mem) __acev_memp = (mem); \ + __typeof (*mem) __acev_ret; \ + __typeof (*mem) __acev_newval = (newval); \ + \ + __sparc32_atomic_do_lock24 (__acev_memp); \ + __acev_ret = *__acev_memp & 0xffffff; \ + *__acev_memp = __acev_newval; \ + __asm __volatile ("" ::: "memory"); \ + __acev_ret; }) + +#ifdef SHARED + +/* When dynamically linked, we assume pre-v9 libraries are only ever + used on pre-v9 CPU. */ +# define __atomic_is_v9 0 + +# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ + __v7_compare_and_exchange_val_acq (mem, newval, oldval) + +# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \ + __v7_compare_and_exchange_bool_acq (mem, newval, oldval) + +# define atomic_exchange_acq(mem, newval) \ + __v7_exchange_acq (mem, newval) + +# define atomic_exchange_and_add(mem, value) \ + __v7_exchange_and_add (mem, value) + +# define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \ + ({ \ + if (sizeof (*mem) != 4) \ + abort (); \ + __v7_compare_and_exchange_val_24_acq (mem, newval, oldval); }) + +# define atomic_exchange_24_rel(mem, newval) \ + ({ \ + if (sizeof (*mem) != 4) \ + abort (); \ + __v7_exchange_24_rel (mem, newval); }) + +# define atomic_full_barrier() __asm ("" ::: "memory") +# define atomic_read_barrier() atomic_full_barrier () +# define atomic_write_barrier() atomic_full_barrier () + +#else + +/* In libc.a/libpthread.a etc. we don't know if we'll be run on + pre-v9 or v9 CPU. To be interoperable with dynamically linked + apps on v9 CPUs e.g. with process shared primitives, use cas insn + on v9 CPUs and ldstub on pre-v9. */ + +extern uint64_t _dl_hwcap __attribute__((weak)); +# define __atomic_is_v9 \ + (__builtin_expect (&_dl_hwcap != 0, 1) \ + && __builtin_expect (_dl_hwcap & HWCAP_SPARC_V9, HWCAP_SPARC_V9)) + +# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ + ({ \ + __typeof (*mem) __acev_wret; \ + if (sizeof (*mem) != 4) \ + abort (); \ + if (__atomic_is_v9) \ + __acev_wret \ + = __v9_compare_and_exchange_val_32_acq (mem, newval, oldval);\ + else \ + __acev_wret \ + = __v7_compare_and_exchange_val_acq (mem, newval, oldval); \ + __acev_wret; }) + +# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \ + ({ \ + int __acev_wret; \ + if (sizeof (*mem) != 4) \ + abort (); \ + if (__atomic_is_v9) \ + { \ + __typeof (oldval) __acev_woldval = (oldval); \ + __acev_wret \ + = __v9_compare_and_exchange_val_32_acq (mem, newval, \ + __acev_woldval) \ + != __acev_woldval; \ + } \ + else \ + __acev_wret \ + = __v7_compare_and_exchange_bool_acq (mem, newval, oldval); \ + __acev_wret; }) + +# define atomic_exchange_rel(mem, newval) \ + ({ \ + __typeof (*mem) __acev_wret; \ + if (sizeof (*mem) != 4) \ + abort (); \ + if (__atomic_is_v9) \ + { \ + __typeof (mem) __acev_wmemp = (mem); \ + __typeof (*(mem)) __acev_wval = (newval); \ + do \ + __acev_wret = *__acev_wmemp; \ + while (__builtin_expect \ + (__v9_compare_and_exchange_val_32_acq (__acev_wmemp,\ + __acev_wval, \ + __acev_wret) \ + != __acev_wret, 0)); \ + } \ + else \ + __acev_wret = __v7_exchange_acq (mem, newval); \ + __acev_wret; }) + +# define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \ + ({ \ + __typeof (*mem) __acev_wret; \ + if (sizeof (*mem) != 4) \ + abort (); \ + if (__atomic_is_v9) \ + __acev_wret \ + = __v9_compare_and_exchange_val_32_acq (mem, newval, oldval);\ + else \ + __acev_wret \ + = __v7_compare_and_exchange_val_24_acq (mem, newval, oldval);\ + __acev_wret; }) + +# define atomic_exchange_24_rel(mem, newval) \ + ({ \ + __typeof (*mem) __acev_w24ret; \ + if (sizeof (*mem) != 4) \ + abort (); \ + if (__atomic_is_v9) \ + __acev_w24ret = atomic_exchange_rel (mem, newval); \ + else \ + __acev_w24ret = __v7_exchange_24_rel (mem, newval); \ + __acev_w24ret; }) + +#define atomic_full_barrier() \ + do { \ + if (__atomic_is_v9) \ + /* membar #LoadLoad | #LoadStore | #StoreLoad | #StoreStore */ \ + __asm __volatile (".word 0x8143e00f" : : : "memory"); \ + else \ + __asm __volatile ("" : : : "memory"); \ + } while (0) + +#define atomic_read_barrier() \ + do { \ + if (__atomic_is_v9) \ + /* membar #LoadLoad | #LoadStore */ \ + __asm __volatile (".word 0x8143e005" : : : "memory"); \ + else \ + __asm __volatile ("" : : : "memory"); \ + } while (0) + +#define atomic_write_barrier() \ + do { \ + if (__atomic_is_v9) \ + /* membar #LoadStore | #StoreStore */ \ + __asm __volatile (".word 0x8143e00c" : : : "memory"); \ + else \ + __asm __volatile ("" : : : "memory"); \ + } while (0) + +#endif + +#include <sysdep.h> + +#endif /* atomic-machine.h */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/backtrace.h b/REORG.TODO/sysdeps/sparc/sparc32/backtrace.h new file mode 100644 index 0000000000..089f8b4d28 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/backtrace.h @@ -0,0 +1,7 @@ +/* Private macros for guiding the backtrace implementation, sparc32 + version. */ + +#define backtrace_flush_register_windows() \ + asm volatile ("ta %0" : : "i" (ST_FLUSH_WINDOWS)) + +#define BACKTRACE_STACK_BIAS 0 diff --git a/REORG.TODO/sysdeps/sparc/sparc32/bits/setjmp.h b/REORG.TODO/sysdeps/sparc/sparc32/bits/setjmp.h new file mode 100644 index 0000000000..fbab934d6b --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/bits/setjmp.h @@ -0,0 +1,26 @@ +/* Copyright (C) 1997-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 the machine-dependent type `jmp_buf'. SPARC version. */ + +#ifndef _SETJMP_H +# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead." +#endif + +#ifndef _ASM +typedef int __jmp_buf[3]; +#endif diff --git a/REORG.TODO/sysdeps/sparc/sparc32/bits/wordsize.h b/REORG.TODO/sysdeps/sparc/sparc32/bits/wordsize.h new file mode 100644 index 0000000000..2f66f10d72 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/bits/wordsize.h @@ -0,0 +1,11 @@ +/* Determine the wordsize from the preprocessor defines. */ + +#if defined __arch64__ || defined __sparcv9 +# define __WORDSIZE 64 +# define __WORDSIZE_TIME64_COMPAT32 1 +#else +# define __WORDSIZE 32 +# define __WORDSIZE_TIME64_COMPAT32 0 +# define __WORDSIZE32_SIZE_ULONG 0 +# define __WORDSIZE32_PTRDIFF_LONG 0 +#endif diff --git a/REORG.TODO/sysdeps/sparc/sparc32/bsd-_setjmp.S b/REORG.TODO/sysdeps/sparc/sparc32/bsd-_setjmp.S new file mode 100644 index 0000000000..4e6a2da560 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/bsd-_setjmp.S @@ -0,0 +1 @@ +/* _setjmp is in setjmp.S */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/bsd-setjmp.S b/REORG.TODO/sysdeps/sparc/sparc32/bsd-setjmp.S new file mode 100644 index 0000000000..1da848d2f1 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/bsd-setjmp.S @@ -0,0 +1 @@ +/* setjmp is in setjmp.S */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/bzero.c b/REORG.TODO/sysdeps/sparc/sparc32/bzero.c new file mode 100644 index 0000000000..37f0f6f993 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/bzero.c @@ -0,0 +1 @@ +/* bzero is in memset.S */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/divrem.m4 b/REORG.TODO/sysdeps/sparc/sparc32/divrem.m4 new file mode 100644 index 0000000000..30d532ad77 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/divrem.m4 @@ -0,0 +1,232 @@ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * NAME name of function to generate + * OP OP=div => %o0 / %o1; OP=rem => %o0 % %o1 + * S S=true => signed; S=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top `decade' of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + +define(N, `4')dnl +define(WORDSIZE, `32')dnl +define(TOPBITS, eval(WORDSIZE - N*((WORDSIZE-1)/N)))dnl +dnl +define(dividend, `%o0')dnl +define(divisor, `%o1')dnl +define(Q, `%o2')dnl +define(R, `%o3')dnl +define(ITER, `%o4')dnl +define(V, `%o5')dnl +dnl +dnl m4 reminder: ifelse(a,b,c,d) => if a is b, then c, else d +define(T, `%g1')dnl +define(SC, `%g2')dnl +ifelse(S, `true', `define(SIGN, `%g3')')dnl + +dnl +dnl This is the recursive definition for developing quotient digits. +dnl +dnl Parameters: +dnl $1 the current depth, 1 <= $1 <= N +dnl $2 the current accumulation of quotient bits +dnl N max depth +dnl +dnl We add a new bit to $2 and either recurse or insert the bits in +dnl the quotient. R, Q, and V are inputs and outputs as defined above; +dnl the condition codes are expected to reflect the input R, and are +dnl modified to reflect the output R. +dnl +define(DEVELOP_QUOTIENT_BITS, +` ! depth $1, accumulated bits $2 + bl LOC($1.eval(2**N+$2)) + srl V,1,V + ! remainder is positive + subcc R,V,R + ifelse($1, N, + ` b 9f + add Q, ($2*2+1), Q + ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2+1)')') +LOC($1.eval(2**N+$2)): + ! remainder is negative + addcc R,V,R + ifelse($1, N, + ` b 9f + add Q, ($2*2-1), Q + ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')') + ifelse($1, 1, `9:')')dnl + +#include <sysdep.h> +#include <sys/trap.h> + +ENTRY(NAME) +ifelse(S, `true', +` ! compute sign of result; if neither is negative, no problem + orcc divisor, dividend, %g0 ! either negative? + bge 2f ! no, go do the divide +ifelse(OP, `div', +` xor divisor, dividend, SIGN ! compute sign in any case', +` mov dividend, SIGN ! sign of remainder matches dividend') + tst divisor + bge 1f + tst dividend + ! divisor is definitely negative; dividend might also be negative + bge 2f ! if dividend not negative... + sub %g0, divisor, divisor ! in any case, make divisor nonneg +1: ! dividend is negative, divisor is nonnegative + sub %g0, dividend, dividend ! make dividend nonnegative +2: +') + ! Ready to divide. Compute size of quotient; scale comparand. + orcc divisor, %g0, V + bne 1f + mov dividend, R + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp R, V ! if divisor exceeds dividend, done + blu LOC(got_result) ! (and algorithm fails otherwise) + clr Q + sethi %hi(1 << (WORDSIZE - TOPBITS - 1)), T + cmp R, T + blu LOC(not_really_big) + clr ITER + + ! `Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R.' + 1: + cmp V, T + bgeu 3f + mov 1, SC + sll V, N, V + b 1b + add ITER, 1, ITER + + ! Now compute SC. + 2: addcc V, V, V + bcc LOC(not_too_big) + add SC, 1, SC + + ! We get here if the divisor overflowed while shifting. + ! This means that R has the high-order bit set. + ! Restore V and subtract from R. + sll T, TOPBITS, T ! high order bit + srl V, 1, V ! rest of V + add V, T, V + b LOC(do_single_div) + sub SC, 1, SC + + LOC(not_too_big): + 3: cmp V, R + blu 2b + nop + be LOC(do_single_div) + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! V > R: went too far: back up 1 step + ! srl V, 1, V + ! dec SC + ! do single-bit divide steps + ! + ! We have to be careful here. We know that R >= V, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if R >= 0. Because both R and V may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + LOC(do_single_div): + subcc SC, 1, SC + bl LOC(end_regular_divide) + nop + sub R, V, R + mov 1, Q + b LOC(end_single_divloop) + nop + LOC(single_divloop): + sll Q, 1, Q + bl 1f + srl V, 1, V + ! R >= 0 + sub R, V, R + b 2f + add Q, 1, Q + 1: ! R < 0 + add R, V, R + sub Q, 1, Q + 2: + LOC(end_single_divloop): + subcc SC, 1, SC + bge LOC(single_divloop) + tst R + b,a LOC(end_regular_divide) + +LOC(not_really_big): +1: + sll V, N, V + cmp V, R + bleu 1b + addcc ITER, 1, ITER + be LOC(got_result) + sub ITER, 1, ITER + + tst R ! set up for initial iteration +LOC(divloop): + sll Q, N, Q + DEVELOP_QUOTIENT_BITS(1, 0) +LOC(end_regular_divide): + subcc ITER, 1, ITER + bge LOC(divloop) + tst R + bl,a LOC(got_result) + ! non-restoring fixup here (one instruction only!) +ifelse(OP, `div', +` sub Q, 1, Q +', ` add R, divisor, R +') + +LOC(got_result): +ifelse(S, `true', +` ! check to see if answer should be < 0 + tst SIGN + bl,a 1f + ifelse(OP, `div', `sub %g0, Q, Q', `sub %g0, R, R') +1:') + retl + ifelse(OP, `div', `mov Q, %o0', `mov R, %o0') + +END(NAME) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/dl-irel.h b/REORG.TODO/sysdeps/sparc/sparc32/dl-irel.h new file mode 100644 index 0000000000..56c155e4d5 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/dl-irel.h @@ -0,0 +1,62 @@ +/* Machine-dependent ELF indirect relocation inline functions. + SPARC 32-bit version. + Copyright (C) 2010-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_IREL_H +#define _DL_IREL_H + +#include <stdio.h> +#include <unistd.h> +#include <dl-plt.h> +#include <ldsodefs.h> + +#define ELF_MACHINE_IRELA 1 + +static inline Elf32_Addr +__attribute ((always_inline)) +elf_ifunc_invoke (Elf32_Addr addr) +{ + return ((Elf32_Addr (*) (int)) (addr)) (GLRO(dl_hwcap)); +} + +static inline void +__attribute ((always_inline)) +elf_irela (const Elf32_Rela *reloc) +{ + unsigned int r_type = ELF32_R_TYPE (reloc->r_info); + + if (__glibc_likely (r_type == R_SPARC_IRELATIVE)) + { + Elf32_Addr *const reloc_addr = (void *) reloc->r_offset; + Elf32_Addr value = elf_ifunc_invoke(reloc->r_addend); + *reloc_addr = value; + } + else if (__glibc_likely (r_type == R_SPARC_JMP_IREL)) + { + Elf32_Addr *const reloc_addr = (void *) reloc->r_offset; + Elf32_Addr value = elf_ifunc_invoke(reloc->r_addend); + + sparc_fixup_plt (reloc, reloc_addr, value, 0, 1); + } + else if (r_type == R_SPARC_NONE) + ; + else + __libc_fatal ("unexpected reloc type in static binary"); +} + +#endif /* dl-irel.h */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/dl-machine.h b/REORG.TODO/sysdeps/sparc/sparc32/dl-machine.h new file mode 100644 index 0000000000..95f673270e --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/dl-machine.h @@ -0,0 +1,568 @@ +/* Machine-dependent ELF dynamic relocation inline functions. SPARC 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/>. */ + +#ifndef dl_machine_h +#define dl_machine_h + +#define ELF_MACHINE_NAME "sparc" + +#include <string.h> +#include <sys/param.h> +#include <ldsodefs.h> +#include <sysdep.h> +#include <tls.h> +#include <dl-plt.h> +#include <elf/dl-hwcaps.h> + +/* Return nonzero iff ELF header is compatible with the running host. */ +static inline int +elf_machine_matches_host (const Elf32_Ehdr *ehdr) +{ + if (ehdr->e_machine == EM_SPARC) + return 1; + else if (ehdr->e_machine == EM_SPARC32PLUS) + { +#if HAVE_TUNABLES || defined SHARED + uint64_t hwcap_mask = GET_HWCAP_MASK(); + return GLRO(dl_hwcap) & hwcap_mask & HWCAP_SPARC_V9; +#else + return GLRO(dl_hwcap) & HWCAP_SPARC_V9; +#endif + } + else + return 0; +} + +/* We have to do this because elf_machine_{dynamic,load_address} can be + invoked from functions that have no GOT references, and thus the compiler + has no obligation to load the PIC register. */ +#define LOAD_PIC_REG(PIC_REG) \ +do { register Elf32_Addr pc __asm("o7"); \ + __asm("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" \ + "call 1f\n\t" \ + "add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n" \ + "1:\tadd %1, %0, %1" \ + : "=r" (pc), "=r" (PIC_REG)); \ +} while (0) + +/* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. */ +static inline Elf32_Addr +elf_machine_dynamic (void) +{ + register Elf32_Addr *got asm ("%l7"); + + LOAD_PIC_REG (got); + + return *got; +} + +/* Return the run-time load address of the shared object. */ +static inline Elf32_Addr +elf_machine_load_address (void) +{ + register Elf32_Addr *pc __asm ("%o7"), *got __asm ("%l7"); + + __asm ("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" + "call 1f\n\t" + " add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t" + "call _DYNAMIC\n\t" + "call _GLOBAL_OFFSET_TABLE_\n" + "1:\tadd %1, %0, %1\n\t" : "=r" (pc), "=r" (got)); + + /* got is now l_addr + _GLOBAL_OFFSET_TABLE_ + *got is _DYNAMIC + pc[2]*4 is l_addr + _DYNAMIC - (long)pc - 8 + pc[3]*4 is l_addr + _GLOBAL_OFFSET_TABLE_ - (long)pc - 12 */ + return (Elf32_Addr) got - *got + (pc[2] - pc[3]) * 4 - 4; +} + +/* Set up the loaded object described by L so its unrelocated PLT + entries will jump to the on-demand fixup code in dl-runtime.c. */ + +static inline int +elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) +{ + Elf32_Addr *plt; + extern void _dl_runtime_resolve (Elf32_Word); + extern void _dl_runtime_profile (Elf32_Word); + + if (l->l_info[DT_JMPREL] && lazy) + { + Elf32_Addr rfunc; + + /* The entries for functions in the PLT have not yet been filled in. + Their initial contents will arrange when called to set the high 22 + bits of %g1 with an offset into the .rela.plt section and jump to + the beginning of the PLT. */ + plt = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]); + if (__builtin_expect(profile, 0)) + { + rfunc = (Elf32_Addr) &_dl_runtime_profile; + + if (GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), l)) + GL(dl_profile_map) = l; + } + else + { + rfunc = (Elf32_Addr) &_dl_runtime_resolve; + } + + /* The beginning of the PLT does: + + sethi %hi(_dl_runtime_{resolve,profile}), %g2 + pltpc: jmpl %g2 + %lo(_dl_runtime_{resolve,profile}), %g2 + nop + .word MAP + + The PC value (pltpc) saved in %g2 by the jmpl points near the + location where we store the link_map pointer for this object. */ + + plt[0] = 0x05000000 | ((rfunc >> 10) & 0x003fffff); + plt[1] = 0x85c0a000 | (rfunc & 0x3ff); + plt[2] = OPCODE_NOP; /* Fill call delay slot. */ + plt[3] = (Elf32_Addr) l; + if (__builtin_expect (l->l_info[VALIDX(DT_GNU_PRELINKED)] != NULL, 0) + || __builtin_expect (l->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL, 0)) + { + /* Need to reinitialize .plt to undo prelinking. */ + Elf32_Rela *rela = (Elf32_Rela *) D_PTR (l, l_info[DT_JMPREL]); + Elf32_Rela *relaend + = (Elf32_Rela *) ((char *) rela + + l->l_info[DT_PLTRELSZ]->d_un.d_val); +#if !defined RTLD_BOOTSTRAP && !defined __sparc_v9__ + /* Note that we don't mask the hwcap here, as the flush is + essential to functionality on those cpu's that implement it. + For sparcv9 we can assume flush is present. */ + const int do_flush = GLRO(dl_hwcap) & HWCAP_SPARC_FLUSH; +#else + const int do_flush = 1; +#endif + + /* prelink must ensure there are no R_SPARC_NONE relocs left + in .rela.plt. */ + while (rela < relaend) + { + *(unsigned int *) (rela->r_offset + l->l_addr) + = OPCODE_SETHI_G1 | (rela->r_offset + l->l_addr + - (Elf32_Addr) plt); + *(unsigned int *) (rela->r_offset + l->l_addr + 4) + = OPCODE_BA | ((((Elf32_Addr) plt + - rela->r_offset - l->l_addr - 4) >> 2) + & 0x3fffff); + if (do_flush) + { + __asm __volatile ("flush %0" : : "r" (rela->r_offset + + l->l_addr)); + __asm __volatile ("flush %0+4" : : "r" (rela->r_offset + + l->l_addr)); + } + ++rela; + } + } + } + + return lazy; +} + +/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so + PLT entries should not be allowed to define the value. + ELF_RTYPE_CLASS_COPY iff TYPE should not be allowed to resolve to one + of the main executable's symbols, as for a COPY reloc. */ +#define elf_machine_type_class(type) \ + ((((type) == R_SPARC_JMP_SLOT \ + || ((type) >= R_SPARC_TLS_GD_HI22 && (type) <= R_SPARC_TLS_TPOFF64)) \ + * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_SPARC_COPY) * ELF_RTYPE_CLASS_COPY)) + +/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ +#define ELF_MACHINE_JMP_SLOT R_SPARC_JMP_SLOT + +/* The SPARC never uses Elf32_Rel relocations. */ +#define ELF_MACHINE_NO_REL 1 +#define ELF_MACHINE_NO_RELA 0 + +/* Undo the sub %sp, 6*4, %sp; add %sp, 22*4, %o0 below to get at the + value we want in __libc_stack_end. */ +#define DL_STACK_END(cookie) \ + ((void *) (((long) (cookie)) - (22 - 6) * 4)) + +/* 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. */ + +#define RTLD_GOT_ADDRESS(pic_reg, reg, symbol) \ + "sethi %gdop_hix22(" #symbol "), " #reg "\n\t" \ + "xor " #reg ", %gdop_lox10(" #symbol "), " #reg "\n\t" \ + "ld [" #pic_reg " + " #reg "], " #reg ", %gdop(" #symbol ")" + +#define RTLD_START __asm__ ("\ + .text\n\ + .globl _start\n\ + .type _start, @function\n\ + .align 32\n\ +_start:\n\ + /* Allocate space for functions to drop their arguments. */\n\ + sub %sp, 6*4, %sp\n\ + /* Pass pointer to argument block to _dl_start. */\n\ + call _dl_start\n\ + add %sp, 22*4, %o0\n\ + /* FALTHRU */\n\ + .globl _dl_start_user\n\ + .type _dl_start_user, @function\n\ +_dl_start_user:\n\ + /* Load the PIC register. */\n\ +1: call 2f\n\ + sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\ +2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\ + add %l7, %o7, %l7\n\ + /* Save the user entry point address in %l0 */\n\ + mov %o0, %l0\n\ + /* See if we were run as a command with the executable file name as an\n\ + extra leading argument. If so, adjust the contents of the stack. */\n\ + " RTLD_GOT_ADDRESS(%l7, %g2, _dl_skip_args) "\n\ + ld [%g2], %i0\n\ + tst %i0\n\ + beq 3f\n\ + ld [%sp+22*4], %i5 /* load argc */\n\ + /* Find out how far to shift. */\n\ + " RTLD_GOT_ADDRESS(%l7, %l3, _dl_argv) "\n\ + sub %i5, %i0, %i5\n\ + ld [%l3], %l4\n\ + sll %i0, 2, %i2\n\ + st %i5, [%sp+22*4]\n\ + sub %l4, %i2, %l4\n\ + add %sp, 23*4, %i1\n\ + add %i1, %i2, %i2\n\ + st %l4, [%l3]\n\ + /* Copy down argv */\n\ +21: ld [%i2], %i3\n\ + add %i2, 4, %i2\n\ + tst %i3\n\ + st %i3, [%i1]\n\ + bne 21b\n\ + add %i1, 4, %i1\n\ + /* Copy down env */\n\ +22: ld [%i2], %i3\n\ + add %i2, 4, %i2\n\ + tst %i3\n\ + st %i3, [%i1]\n\ + bne 22b\n\ + add %i1, 4, %i1\n\ + /* Copy down auxiliary table. */\n\ +23: ld [%i2], %i3\n\ + ld [%i2+4], %i4\n\ + add %i2, 8, %i2\n\ + tst %i3\n\ + st %i3, [%i1]\n\ + st %i4, [%i1+4]\n\ + bne 23b\n\ + add %i1, 8, %i1\n\ + /* %o0 = _dl_loaded, %o1 = argc, %o2 = argv, %o3 = envp. */\n\ +3: " RTLD_GOT_ADDRESS(%l7, %o0, _rtld_local) "\n\ + add %sp, 23*4, %o2\n\ + sll %i5, 2, %o3\n\ + add %o3, 4, %o3\n\ + mov %i5, %o1\n\ + add %o2, %o3, %o3\n\ + call _dl_init\n\ + ld [%o0], %o0\n\ + /* Pass our finalizer function to the user in %g1. */\n\ + " RTLD_GOT_ADDRESS(%l7, %g1, _dl_fini) "\n\ + /* Jump to the user's entry point and deallocate the extra stack we got. */\n\ + jmp %l0\n\ + add %sp, 6*4, %sp\n\ + .size _dl_start_user, . - _dl_start_user\n\ + .previous"); + +static inline Elf32_Addr +elf_machine_fixup_plt (struct link_map *map, lookup_t t, + const Elf32_Rela *reloc, + Elf32_Addr *reloc_addr, Elf32_Addr value) +{ +#ifdef __sparc_v9__ + /* Sparc v9 can assume flush is always present. */ + const int do_flush = 1; +#else + /* Note that we don't mask the hwcap here, as the flush is essential to + functionality on those cpu's that implement it. */ + const int do_flush = GLRO(dl_hwcap) & HWCAP_SPARC_FLUSH; +#endif + return sparc_fixup_plt (reloc, reloc_addr, value, 1, do_flush); +} + +/* Return the final value of a plt relocation. */ +static inline Elf32_Addr +elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, + Elf32_Addr value) +{ + return value + reloc->r_addend; +} + +#endif /* dl_machine_h */ + +#define ARCH_LA_PLTENTER sparc32_gnu_pltenter +#define ARCH_LA_PLTEXIT sparc32_gnu_pltexit + +#ifdef RESOLVE_MAP + +/* 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_rela (struct link_map *map, const Elf32_Rela *reloc, + const Elf32_Sym *sym, const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) +{ + Elf32_Addr *const reloc_addr = reloc_addr_arg; +#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP + const Elf32_Sym *const refsym = sym; +#endif + Elf32_Addr value; + const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); +#if !defined RESOLVE_CONFLICT_FIND_MAP + struct link_map *sym_map = NULL; +#endif + +#if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC + /* 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 (_dl_rtld_map); +#endif + + if (__glibc_unlikely (r_type == R_SPARC_NONE)) + return; + + if (__glibc_unlikely (r_type == R_SPARC_SIZE32)) + { + *reloc_addr = sym->st_size + reloc->r_addend; + return; + } + +#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC + if (__glibc_unlikely (r_type == R_SPARC_RELATIVE)) + { +# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC + if (map != &_dl_rtld_map) /* Already done in rtld itself. */ +# endif + *reloc_addr += map->l_addr + reloc->r_addend; + return; + } +#endif + +#ifndef RESOLVE_CONFLICT_FIND_MAP + if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0) + && sym->st_shndx != SHN_UNDEF) + { + value = map->l_addr; + } + else + { + sym_map = RESOLVE_MAP (&sym, version, r_type); + value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value; + } +#else + value = 0; +#endif + + value += reloc->r_addend; /* Assume copy relocs have zero addend. */ + + if (sym != NULL + && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0) + && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1) + && __builtin_expect (!skip_ifunc, 1)) + { + value = ((Elf32_Addr (*) (int)) value) (GLRO(dl_hwcap)); + } + + switch (r_type) + { +#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP + case R_SPARC_COPY: + if (sym == NULL) + /* This can happen in trace mode if an object could not be + found. */ + break; + if (sym->st_size > refsym->st_size + || (GLRO(dl_verbose) && sym->st_size < refsym->st_size)) + { + 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_arg, (void *) value, + MIN (sym->st_size, refsym->st_size)); + break; +#endif + case R_SPARC_GLOB_DAT: + case R_SPARC_32: + *reloc_addr = value; + break; + case R_SPARC_IRELATIVE: + value = ((Elf32_Addr (*) (int)) value) (GLRO(dl_hwcap)); + *reloc_addr = value; + break; + case R_SPARC_JMP_IREL: + value = ((Elf32_Addr (*) (int)) value) (GLRO(dl_hwcap)); + /* Fall thru */ + case R_SPARC_JMP_SLOT: + { +#if !defined RTLD_BOOTSTRAP && !defined __sparc_v9__ + /* Note that we don't mask the hwcap here, as the flush is + essential to functionality on those cpu's that implement + it. For sparcv9 we can assume flush is present. */ + const int do_flush = GLRO(dl_hwcap) & HWCAP_SPARC_FLUSH; +#else + /* Unfortunately, this is necessary, so that we can ensure + ld.so will not execute corrupt PLT entry instructions. */ + const int do_flush = 1; +#endif + /* At this point we don't need to bother with thread safety, + so we can optimize the first instruction of .plt out. */ + sparc_fixup_plt (reloc, reloc_addr, value, 0, do_flush); + } + break; +#ifndef RESOLVE_CONFLICT_FIND_MAP + case R_SPARC_TLS_DTPMOD32: + /* Get the information from the link map returned by the + resolv function. */ + if (sym_map != NULL) + *reloc_addr = sym_map->l_tls_modid; + break; + case R_SPARC_TLS_DTPOFF32: + /* During relocation all TLS symbols are defined and used. + Therefore the offset is already correct. */ + *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend; + break; + case R_SPARC_TLS_TPOFF32: + /* The offset is negative, forward from the thread pointer. */ + /* We know the offset of object the symbol is contained in. + It is a negative value which will be added to the + thread pointer. */ + if (sym != NULL) + { + CHECK_STATIC_TLS (map, sym_map); + *reloc_addr = sym->st_value - sym_map->l_tls_offset + + reloc->r_addend; + } + break; +# ifndef RTLD_BOOTSTRAP + case R_SPARC_TLS_LE_HIX22: + case R_SPARC_TLS_LE_LOX10: + if (sym != NULL) + { + CHECK_STATIC_TLS (map, sym_map); + value = sym->st_value - sym_map->l_tls_offset + + reloc->r_addend; + if (r_type == R_SPARC_TLS_LE_HIX22) + *reloc_addr = (*reloc_addr & 0xffc00000) | ((~value) >> 10); + else + *reloc_addr = (*reloc_addr & 0xffffe000) | (value & 0x3ff) + | 0x1c00; + } + break; +# endif +#endif +#ifndef RTLD_BOOTSTRAP + case R_SPARC_8: + *(char *) reloc_addr = value; + break; + case R_SPARC_16: + *(short *) reloc_addr = value; + break; + case R_SPARC_DISP8: + *(char *) reloc_addr = (value - (Elf32_Addr) reloc_addr); + break; + case R_SPARC_DISP16: + *(short *) reloc_addr = (value - (Elf32_Addr) reloc_addr); + break; + case R_SPARC_DISP32: + *reloc_addr = (value - (Elf32_Addr) reloc_addr); + break; + case R_SPARC_LO10: + *reloc_addr = (*reloc_addr & ~0x3ff) | (value & 0x3ff); + break; + case R_SPARC_WDISP30: + *reloc_addr = ((*reloc_addr & 0xc0000000) + | ((value - (unsigned int) reloc_addr) >> 2)); + break; + case R_SPARC_HI22: + *reloc_addr = (*reloc_addr & 0xffc00000) | (value >> 10); + break; + case R_SPARC_UA16: + ((unsigned char *) reloc_addr_arg) [0] = value >> 8; + ((unsigned char *) reloc_addr_arg) [1] = value; + break; + case R_SPARC_UA32: + ((unsigned char *) reloc_addr_arg) [0] = value >> 24; + ((unsigned char *) reloc_addr_arg) [1] = value >> 16; + ((unsigned char *) reloc_addr_arg) [2] = value >> 8; + ((unsigned char *) reloc_addr_arg) [3] = value; + break; +#endif +#if !defined RTLD_BOOTSTRAP || defined _NDEBUG + default: + _dl_reloc_bad_type (map, r_type, 0); + break; +#endif + } +} + +auto inline void +__attribute__ ((always_inline)) +elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + void *const reloc_addr_arg) +{ + Elf32_Addr *const reloc_addr = reloc_addr_arg; + *reloc_addr += l_addr + reloc->r_addend; +} + +auto inline void +__attribute__ ((always_inline)) +elf_machine_lazy_rel (struct link_map *map, + Elf32_Addr l_addr, const Elf32_Rela *reloc, + int skip_ifunc) +{ + Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); + + if (__glibc_likely (r_type == R_SPARC_JMP_SLOT)) + ; + else if (r_type == R_SPARC_JMP_IREL) + { + Elf32_Addr value = map->l_addr + reloc->r_addend; + if (__glibc_likely (!skip_ifunc)) + value = ((Elf32_Addr (*) (int)) value) (GLRO(dl_hwcap)); + sparc_fixup_plt (reloc, reloc_addr, value, 1, 1); + } + else if (r_type == R_SPARC_NONE) + ; + else + _dl_reloc_bad_type (map, r_type, 1); +} + +#endif /* RESOLVE_MAP */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/dl-plt.h b/REORG.TODO/sysdeps/sparc/sparc32/dl-plt.h new file mode 100644 index 0000000000..0a583713d7 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/dl-plt.h @@ -0,0 +1,100 @@ +/* PLT fixups. Sparc 32-bit 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/>. */ + +#ifndef _DL_PLT_H +#define _DL_PLT_H + +/* Some SPARC opcodes we need to use for self-modifying code. */ +#define OPCODE_NOP 0x01000000 /* nop */ +#define OPCODE_CALL 0x40000000 /* call ?; add PC-rel word address */ +#define OPCODE_SETHI_G1 0x03000000 /* sethi ?, %g1; add value>>10 */ +#define OPCODE_JMP_G1 0x81c06000 /* jmp %g1+?; add lo 10 bits of value */ +#define OPCODE_SAVE_SP 0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */ +#define OPCODE_BA 0x30800000 /* b,a ?; add PC-rel word address */ +#define OPCODE_BA_PT 0x30480000 /* ba,a,pt %icc, ?; add PC-rel word address */ + +static inline __attribute__ ((always_inline)) Elf32_Addr +sparc_fixup_plt (const Elf32_Rela *reloc, Elf32_Addr *reloc_addr, + Elf32_Addr value, int t, int do_flush) +{ + Elf32_Sword disp; + + /* 't' is '0' if we are resolving this PLT entry for RTLD bootstrap, + in which case we'll be resolving all PLT entries and thus can + optimize by overwriting instructions starting at the first PLT entry + instruction and we need not be mindful of thread safety. + + Otherwise, 't' is '1'. */ + reloc_addr += t; + disp = value - (Elf32_Addr) reloc_addr; + + if (disp >= -0x800000 && disp < 0x800000) + { + unsigned int insn = OPCODE_BA | ((disp >> 2) & 0x3fffff); + +#ifdef __sparc_v9__ + /* On V9 we can do even better by using a branch with + prediction if we fit into the even smaller 19-bit + displacement field. */ + if (disp >= -0x100000 && disp < 0x100000) + insn = OPCODE_BA_PT | ((disp >> 2) & 0x07ffff); +#endif + + /* Even if we are writing just a single branch, we must not + ignore the 't' offset. Consider a case where we have some + PLT slots which can be optimized into a single branch and + some which cannot. Then we can end up with a PLT which looks + like: + + PLT4.0: sethi %(PLT_4_INDEX), %g1 + sethi %(fully_resolved_sym_4), %g1 + jmp %g1 + %lo(fully_resolved_sym_4) + PLT5.0: ba,a fully_resolved_sym_5 + ba,a PLT0.0 + ... + + The delay slot of that jmp must always be either a sethi to + %g1 or a nop. But if we try to place this displacement + branch there, PLT4.0 will jump to fully_resolved_sym_4 for 1 + instruction and then go immediately to + fully_resolved_sym_5. */ + + reloc_addr[0] = insn; + if (do_flush) + __asm __volatile ("flush %0" : : "r"(reloc_addr)); + } + else + { + /* For thread safety, write the instructions from the bottom and + flush before we overwrite the critical "b,a". This of course + need not be done during bootstrapping, since there are no threads. + But we also can't tell if we _can_ use flush, so don't. */ + + reloc_addr[1] = OPCODE_JMP_G1 | (value & 0x3ff); + if (do_flush) + __asm __volatile ("flush %0+4" : : "r"(reloc_addr)); + + reloc_addr[0] = OPCODE_SETHI_G1 | (value >> 10); + if (do_flush) + __asm __volatile ("flush %0" : : "r"(reloc_addr)); + } + + return value; +} + +#endif /* dl-plt.h */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/dl-trampoline.S b/REORG.TODO/sysdeps/sparc/sparc32/dl-trampoline.S new file mode 100644 index 0000000000..acfc9d9208 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/dl-trampoline.S @@ -0,0 +1,187 @@ +/* PLT trampolines. Sparc 32-bit 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 <sysdep.h> + + .text + .align 32 + + /* %g1: PLT offset loaded by PLT entry + * %g2: callers PC, which is PLT0 + 4, and we store the + * link map at PLT0 + 12, therefore we add 8 to get + * the address of the link map + */ + .globl _dl_runtime_resolve + .type _dl_runtime_resolve, @function +_dl_runtime_resolve: + cfi_startproc + + save %sp, -104, %sp + cfi_def_cfa_register(%fp) + cfi_window_save + cfi_register (%o7, %i7) + + ld [%g2 + 8], %o0 + srl %g1, 10, %o1 + call _dl_fixup + sub %o1, 4*12, %o1 + jmp %o0 + restore + + cfi_endproc + + .size _dl_runtime_resolve, .-_dl_runtime_resolve + + /* For the profiling cases we pass in our stack frame + * as the base of the La_sparc32_regs, so it looks + * like: + * %l0 %sp + (0 * 8) + * %l1 %sp + (0 * 8) + 4 + * ... + * %l6 %sp + (3 * 8) + * %l7 %sp + (3 * 8) + 4 + * %i0 %sp + (4 * 8) + * %i1 %sp + (4 * 8) + 4 + * ... + * %i6 %sp + (7 * 8) + * %i7 %sp + (7 * 8) + 4 + * struct_ret_ptr %sp + (8 * 8) + * framesize %sp + (9 * 8) + */ + + .globl _dl_profile_save_regs + .type _dl_profile_save_regs, @function +_dl_profile_save_regs: + cfi_startproc + + std %l0, [%sp + ( 0 * 8)] + std %l2, [%sp + ( 1 * 8)] + std %l4, [%sp + ( 2 * 8)] + std %l6, [%sp + ( 3 * 8)] + std %i0, [%sp + ( 4 * 8)] + std %i2, [%sp + ( 5 * 8)] + std %i4, [%sp + ( 6 * 8)] + std %i6, [%sp + ( 7 * 8)] + ld [%fp + (8 * 8)], %l4 + retl + st %l4, [%sp + (8 * 8)] + + cfi_endproc + + .size _dl_profile_save_regs, .-_dl_profile_save_regs + + /* If we are going to call pltexit, then we must replicate + * the caller's stack frame. + * %o0: PLT resolved function address + */ + .globl _dl_profile_invoke + .type _dl_profile_invoke, @function +_dl_profile_invoke: + cfi_startproc + + add %l0, 7, %l0 + andn %l0, 7, %l0 + add %l0, 2 * 8, %g1 + + sub %sp, %g1, %sp + srl %l0, 3, %l7 + mov %o0, %l1 + mov %i0, %o0 + mov %i1, %o1 + mov %i2, %o2 + mov %i3, %o3 + mov %i4, %o4 + mov %i5, %o5 + cmp %l0, 0 + mov %fp, %l2 + be 2f + add %sp, (11 * 8), %l3 +1: ldd [%l2], %g2 + add %l2, 0x8, %l2 + subcc %l7, 1, %l7 + std %g2, [%l3] + bne 1b + add %l3, 0x8, %l3 + +2: jmpl %l1, %o7 + nop + + std %o0, [%sp + ( 9 * 8)] + std %f0, [%sp + (10 * 8)] + + mov %l5, %o0 + mov %l6, %o1 + add %sp, (11 * 8), %o2 + call _dl_call_pltexit + add %sp, ( 9 * 8), %o3 + + ldd [%sp + ( 9 * 8)], %i0 + ldd [%sp + (10 * 8)], %f0 + + jmpl %i7 + 8, %g0 + restore + + cfi_endproc + + .size _dl_profile_invoke, .-_dl_profile_invoke + + /* %g1: PLT offset loaded by PLT entry + * %g2: callers PC, which is PLT0 + 4, and we store the + * link map at PLT0 + 12, therefore we add 8 to get + * the address of the link map + */ + .align 32 + .globl _dl_runtime_profile + .type _dl_runtime_profile, @function +_dl_runtime_profile: + cfi_startproc + + save %sp, -104, %sp + cfi_def_cfa_register(%fp) + cfi_window_save + cfi_register(%o7, %i7) + + ld [%g2 + 8], %o0 + srl %g1, 10, %o1 + mov %i7, %o2 + sub %o1, 4*12, %o1 + + mov %o0, %l5 + mov %o1, %l6 + + call _dl_profile_save_regs + nop + + mov %sp, %o3 + call _dl_profile_fixup + add %sp, (9 * 8), %o4 + + ld [%sp + (9 * 8)], %l0 + cmp %l0, 0 + bl 1f + nop + + call _dl_profile_invoke + nop + +1: jmp %o0 + restore + + cfi_endproc + + .size _dl_runtime_profile, .-_dl_runtime_profile diff --git a/REORG.TODO/sysdeps/sparc/sparc32/dotmul.S b/REORG.TODO/sysdeps/sparc/sparc32/dotmul.S new file mode 100644 index 0000000000..d497ca672d --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/dotmul.S @@ -0,0 +1,127 @@ +/* + * Signed multiply, from Appendix E of the Sparc Version 8 + * Architecture Manual. + */ + +/* + * Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the upper 32 bits of + * the 64-bit product). + * + * This code optimizes short (less than 13-bit) multiplies. + */ + +#include <sysdep.h> + + +ENTRY(.mul) + mov %o0, %y ! multiplier -> Y + andncc %o0, 0xfff, %g0 ! test bits 12..31 + be LOC(mul_shortway) ! if zero, can do it the short way + andcc %g0, %g0, %o4 ! zero the partial product and clear N and V + + /* + * Long multiply. 32 steps, followed by a final shift step. + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %o1, %o4 ! 13 + mulscc %o4, %o1, %o4 ! 14 + mulscc %o4, %o1, %o4 ! 15 + mulscc %o4, %o1, %o4 ! 16 + mulscc %o4, %o1, %o4 ! 17 + mulscc %o4, %o1, %o4 ! 18 + mulscc %o4, %o1, %o4 ! 19 + mulscc %o4, %o1, %o4 ! 20 + mulscc %o4, %o1, %o4 ! 21 + mulscc %o4, %o1, %o4 ! 22 + mulscc %o4, %o1, %o4 ! 23 + mulscc %o4, %o1, %o4 ! 24 + mulscc %o4, %o1, %o4 ! 25 + mulscc %o4, %o1, %o4 ! 26 + mulscc %o4, %o1, %o4 ! 27 + mulscc %o4, %o1, %o4 ! 28 + mulscc %o4, %o1, %o4 ! 29 + mulscc %o4, %o1, %o4 ! 30 + mulscc %o4, %o1, %o4 ! 31 + mulscc %o4, %o1, %o4 ! 32 + mulscc %o4, %g0, %o4 ! final shift + + ! If %o0 was negative, the result is + ! (%o0 * %o1) + (%o1 << 32)) + ! We fix that here. + +#if 0 + tst %o0 + bge 1f + rd %y, %o0 + + ! %o0 was indeed negative; fix upper 32 bits of result by subtracting + ! %o1 (i.e., return %o4 - %o1 in %o1). + retl + sub %o4, %o1, %o1 + +1: + retl + mov %o4, %o1 +#else + /* Faster code adapted from tege@sics.se's code for umul.S. */ + sra %o0, 31, %o2 ! make mask from sign bit + and %o1, %o2, %o2 ! %o2 = 0 or %o1, depending on sign of %o0 + rd %y, %o0 ! get lower half of product + retl + sub %o4, %o2, %o1 ! subtract compensation + ! and put upper half in place +#endif + +LOC(mul_shortway): + /* + * Short multiply. 12 steps, followed by a final shift step. + * The resulting bits are off by 12 and (32-12) = 20 bit positions, + * but there is no problem with %o0 being negative (unlike above). + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %g0, %o4 ! final shift + + /* + * %o4 has 20 of the bits that should be in the low part of the + * result; %y has the bottom 12 (as %y's top 12). That is: + * + * %o4 %y + * +----------------+----------------+ + * | -12- | -20- | -12- | -20- | + * +------(---------+------)---------+ + * --hi-- ----low-part---- + * + * The upper 12 bits of %o4 should be sign-extended to form the + * high part of the product (i.e., highpart = %o4 >> 20). + */ + + rd %y, %o5 + sll %o4, 12, %o0 ! shift middle bits left 12 + srl %o5, 20, %o5 ! shift low bits right 20, zero fill at left + or %o5, %o0, %o0 ! construct low part of result + retl + sra %o4, 20, %o1 ! ... and extract high part of result + +END(.mul) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/e_sqrt.c b/REORG.TODO/sysdeps/sparc/sparc32/e_sqrt.c new file mode 100644 index 0000000000..4886b0a615 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/e_sqrt.c @@ -0,0 +1,33 @@ +/* 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/>. */ + +#include <errno.h> +#include <math.h> + +#ifndef __GNUC__ + #error This file uses GNU C extensions; you must compile with GCC. +#endif + +/* Return the square root of X. */ +double +__ieee754_sqrt (double x) +{ + register double result; + asm ("fsqrtd %1, %0" : "=f" (result) : "f" (x)); + return result; +} +strong_alias (__ieee754_sqrt, __sqrt_finite) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/fpu/e_sqrtl.c b/REORG.TODO/sysdeps/sparc/sparc32/fpu/e_sqrtl.c new file mode 100644 index 0000000000..1592d58849 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/fpu/e_sqrtl.c @@ -0,0 +1,30 @@ +/* Long double square root, sparc32 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 <math.h> + +extern long double _Q_sqrt(const long double a); + +long double +__ieee754_sqrtl (long double x) +{ + return _Q_sqrt (x); +} + +#include <shlib-compat.h> +versioned_symbol (libm, __ieee754_sqrtl, __sqrtl_finite, GLIBC_2_23); diff --git a/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_copysign.S b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_copysign.S new file mode 100644 index 0000000000..bddbfb2386 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_copysign.S @@ -0,0 +1,31 @@ +/* copysign function, sparc32 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + +ENTRY (__copysign) + sethi %hi(0x80000000), %g1 + and %o2, %g1, %o4 + andn %o0, %g1, %o0 + or %o0, %o4, %o0 + std %o0, [%sp + 72] + retl + ldd [%sp + 72], %f0 +END (__copysign) +weak_alias (__copysign, copysign) \ No newline at end of file diff --git a/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_copysignf.S b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_copysignf.S new file mode 100644 index 0000000000..f2e78962a9 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_copysignf.S @@ -0,0 +1,31 @@ +/* float copysign function, sparc32 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + +ENTRY (__copysignf) + sethi %hi(0x80000000), %g1 + and %o1, %g1, %o4 + andn %o0, %g1, %o0 + or %o0, %o4, %o0 + st %o0, [%sp + 68] + retl + ld [%sp + 68], %f0 +END (__copysignf) +weak_alias (__copysignf, copysignf) \ No newline at end of file diff --git a/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_fabs.S b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_fabs.S new file mode 100644 index 0000000000..fdeda68898 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_fabs.S @@ -0,0 +1,28 @@ +/* Float absolute value, sparc32 version. + Copyright (C) 2011-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> + +ENTRY (__fabs) + st %o0, [%sp+72] + st %o1, [%sp+76] + ldd [%sp+72], %f0 + retl + fabss %f0, %f0 +END (__fabs) +weak_alias (__fabs, fabs) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_fabsf.S b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_fabsf.S new file mode 100644 index 0000000000..12ac9de5c8 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_fabsf.S @@ -0,0 +1,28 @@ +/* Float absolute value, sparc32 version. + Copyright (C) 2006-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2006. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + +ENTRY (__fabsf) + st %o0, [%sp+68] + ld [%sp+68], %f0 + retl + fabss %f0, %f0 +END (__fabsf) +weak_alias (__fabsf, fabsf) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_fabsl.c b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_fabsl.c new file mode 100644 index 0000000000..3c03b92828 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_fabsl.c @@ -0,0 +1,8 @@ +#include <math.h> +#include <math_ldbl_opt.h> + +long double __fabsl (long double x) +{ + return __builtin_fabsl (x); +} +long_double_symbol (libm, __fabsl, fabsl); diff --git a/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_fma.c b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_fma.c new file mode 100644 index 0000000000..8f62605870 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_fma.c @@ -0,0 +1,2 @@ +/* Always use dbl-64 version because long double is emulated in software. */ +#include <sysdeps/ieee754/dbl-64/s_fma.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_signbit.S b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_signbit.S new file mode 100644 index 0000000000..956517022f --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_signbit.S @@ -0,0 +1,30 @@ +/* signbit(). sparc32 version. + 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/>. */ + +#include <sysdep.h> + +ENTRY (__signbit) + retl + srl %o0, 31, %o0 +END (__signbit) + +/* On 32-bit the double version will also always work for + single-precision since in both cases the word with the + sign bit in it is passed always in register %o0. */ +strong_alias (__signbit, __signbitf) +hidden_def (__signbitf) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_signbitf.S b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_signbitf.S new file mode 100644 index 0000000000..91886af6d5 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_signbitf.S @@ -0,0 +1 @@ +/* signbitf is implemented in s_signbit.S */ \ No newline at end of file diff --git a/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_signbitl.S b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_signbitl.S new file mode 100644 index 0000000000..5688186d39 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/fpu/s_signbitl.S @@ -0,0 +1,32 @@ +/* signbitl(). sparc32 version. + 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/>. */ + +#include <sysdep.h> +#include <math_ldbl_opt.h> + +ENTRY (___signbitl) + ld [%o0], %o1 + retl + srl %o1, 31, %o0 +END (___signbitl) + +#if IS_IN (libm) +long_double_symbol (libm, ___signbitl, __signbitl); +#else +long_double_symbol (libc, ___signbitl, __signbitl); +#endif diff --git a/REORG.TODO/sysdeps/sparc/sparc32/fpu/w_sqrt_compat.S b/REORG.TODO/sysdeps/sparc/sparc32/fpu/w_sqrt_compat.S new file mode 100644 index 0000000000..703f228766 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/fpu/w_sqrt_compat.S @@ -0,0 +1,53 @@ +/* sqrt function. sparc32 version. + 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/>. */ + +#include <sysdep.h> + +ENTRY (__sqrt) + clr %g1 + std %g0, [%sp + 72] + std %o0, [%sp + 80] + ldd [%sp + 72], %f8 + ldd [%sp + 80], %f0 + fcmpd %f0, %f8 + fbl 1f + nop +8: retl + fsqrtd %f0, %f0 +1: +#ifdef SHARED + SETUP_PIC_REG_LEAF(o5, g1) + sethi %gdop_hix22(_LIB_VERSION), %g1 + xor %g1, %gdop_lox10(_LIB_VERSION), %g1 + ld [%o5 + %g1], %g1, %gdop(_LIB_VERSION) +#else + sethi %hi(_LIB_VERSION), %g1 + or %g1, %lo(_LIB_VERSION), %g1 +#endif + ld [%g1], %g1 + cmp %g1, -1 + be 8b + mov %o0, %o2 + mov %o1, %o3 + mov 26, %o4 + mov %o7, %g1 + call __kernel_standard + mov %g1, %o7 +END (__sqrt) + +weak_alias (__sqrt, sqrt) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/fpu/w_sqrtf_compat.S b/REORG.TODO/sysdeps/sparc/sparc32/fpu/w_sqrtf_compat.S new file mode 100644 index 0000000000..05d1160378 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/fpu/w_sqrtf_compat.S @@ -0,0 +1,51 @@ +/* sqrtf function. sparc32 version. + 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/>. */ + +#include <sysdep.h> + +ENTRY (__sqrtf) + st %g0, [%sp + 68] + st %o0, [%sp + 72] + ld [%sp + 68], %f8 + ld [%sp + 72], %f0 + fcmps %f0, %f8 + fbl 1f + nop +8: retl + fsqrts %f0, %f0 +1: +#ifdef SHARED + SETUP_PIC_REG_LEAF(o5, g1) + sethi %gdop_hix22(_LIB_VERSION), %g1 + xor %g1, %gdop_lox10(_LIB_VERSION), %g1 + ld [%o5 + %g1], %g1, %gdop(_LIB_VERSION) +#else + sethi %hi(_LIB_VERSION), %g1 + or %g1, %lo(_LIB_VERSION), %g1 +#endif + ld [%g1], %g1 + cmp %g1, -1 + be 8b + mov %o0, %o1 + mov 126, %o2 + mov %o7, %g1 + call __kernel_standard_f + mov %g1, %o7 +END (__sqrtf) + +weak_alias (__sqrtf, sqrtf) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/ieee754.h b/REORG.TODO/sysdeps/sparc/sparc32/ieee754.h new file mode 100644 index 0000000000..94662a350f --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/ieee754.h @@ -0,0 +1,170 @@ +/* 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> + +__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 + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:20; + unsigned int exponent:11; + 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:11; + unsigned int quiet_nan:1; + /* Together these comprise the mantissa. */ + unsigned int mantissa0:19; + 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 + } ieee_nan; + }; + +#define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */ + + +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; +#else + /* 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 + } ieee_nan; + }; + +#define IEEE854_LONG_DOUBLE_BIAS 0x3fff /* Added to exponent. */ + +__END_DECLS + +#endif /* ieee754.h */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/jmpbuf-offsets.h b/REORG.TODO/sysdeps/sparc/sparc32/jmpbuf-offsets.h new file mode 100644 index 0000000000..679c1fa595 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/jmpbuf-offsets.h @@ -0,0 +1,21 @@ +/* Private macros for accessing __jmp_buf contents. SPARC version. + Copyright (C) 2006-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 JB_SP 0 +#define JB_FP 1 +#define JB_PC 2 diff --git a/REORG.TODO/sysdeps/sparc/sparc32/jmpbuf-unwind.h b/REORG.TODO/sysdeps/sparc/sparc32/jmpbuf-unwind.h new file mode 100644 index 0000000000..b497febd91 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/jmpbuf-unwind.h @@ -0,0 +1,47 @@ +/* Copyright (C) 2003-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <setjmp.h> +#include <jmpbuf-offsets.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) \ + ((int) (address) < demangle ((jmpbuf)[JB_SP])) + +#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ + _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) + +static inline uintptr_t __attribute__ ((unused)) +_jmpbuf_sp (__jmp_buf regs) +{ + uintptr_t sp = regs[JB_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 lobngjmp for unwinding. */ +#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/lll_timedlock_wait.c b/REORG.TODO/sysdeps/sparc/sparc32/lll_timedlock_wait.c new file mode 100644 index 0000000000..c2c93faf1b --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/lll_timedlock_wait.c @@ -0,0 +1 @@ +/* __lll_timedlock_wait is in lowlevellock.c. */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/lll_timedwait_tid.c b/REORG.TODO/sysdeps/sparc/sparc32/lll_timedwait_tid.c new file mode 100644 index 0000000000..511608ead9 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/lll_timedwait_tid.c @@ -0,0 +1 @@ +/* __lll_timedwait_tid is in lowlevellock.c. */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/lowlevellock.c b/REORG.TODO/sysdeps/sparc/sparc32/lowlevellock.c new file mode 100644 index 0000000000..e502bf6f25 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/lowlevellock.c @@ -0,0 +1,131 @@ +/* low level locking for pthread library. SPARC version. + Copyright (C) 2003-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <sysdep.h> +#include <lowlevellock.h> +#include <sys/time.h> + + +void +__lll_lock_wait_private (int *futex) +{ + do + { + int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1); + if (oldval != 0) + lll_futex_wait (futex, 2, LLL_PRIVATE); + } + while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0); +} + + +/* These functions don't get included in libc.so */ +#if IS_IN (libpthread) +void +__lll_lock_wait (int *futex, int private) +{ + do + { + int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1); + if (oldval != 0) + lll_futex_wait (futex, 2, private); + } + while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0); +} + + +int +__lll_timedlock_wait (int *futex, const struct timespec *abstime, int private) +{ + /* Reject invalid timeouts. */ + if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) + return EINVAL; + + do + { + struct timeval tv; + struct timespec rt; + + /* Get the current time. */ + (void) __gettimeofday (&tv, NULL); + + /* Compute relative timeout. */ + rt.tv_sec = abstime->tv_sec - tv.tv_sec; + rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; + if (rt.tv_nsec < 0) + { + rt.tv_nsec += 1000000000; + --rt.tv_sec; + } + + /* Already timed out? */ + if (rt.tv_sec < 0) + return ETIMEDOUT; + + /* Wait. */ + int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1); + if (oldval != 0) + lll_futex_timed_wait (futex, 2, &rt, private); + } + while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0); + + return 0; +} + + +int +__lll_timedwait_tid (int *tidp, const struct timespec *abstime) +{ + int tid; + + if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) + return EINVAL; + + /* Repeat until thread terminated. */ + while ((tid = *tidp) != 0) + { + struct timeval tv; + struct timespec rt; + + /* Get the current time. */ + (void) __gettimeofday (&tv, NULL); + + /* Compute relative timeout. */ + rt.tv_sec = abstime->tv_sec - tv.tv_sec; + rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; + if (rt.tv_nsec < 0) + { + rt.tv_nsec += 1000000000; + --rt.tv_sec; + } + + /* Already timed out? */ + if (rt.tv_sec < 0) + return ETIMEDOUT; + + /* Wait until thread terminates. The kernel so far does not use + the private futex operations for this. */ + if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT) + return ETIMEDOUT; + } + + return 0; +} +#endif diff --git a/REORG.TODO/sysdeps/sparc/sparc32/lshift.S b/REORG.TODO/sysdeps/sparc/sparc32/lshift.S new file mode 100644 index 0000000000..5deebdba41 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/lshift.S @@ -0,0 +1,96 @@ +! Sparc __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; see the file COPYING.LIB. If not, +! see <http://www.gnu.org/licenses/>. + + +! INPUT PARAMETERS +! RES_PTR %o0 +! SRC_PTR %o1 +! SIZE %o2 +! CNT %o3 + +#include <sysdep.h> + +ENTRY(__mpn_lshift) + sll %o2,2,%g1 + add %o1,%g1,%o1 ! make %o1 point at end of src + ld [%o1-4],%g2 ! load first limb + sub %g0,%o3,%o5 ! negate shift count + add %o0,%g1,%o0 ! make %o0 point at end of res + add %o2,-1,%o2 + andcc %o2,4-1,%g4 ! number of limbs in first loop + srl %g2,%o5,%g1 ! compute function result + be LOC(0) ! if multiple of 4 limbs, skip first loop + st %g1,[%sp+80] + + sub %o2,%g4,%o2 ! adjust count for main loop + +LOC(loop0): + ld [%o1-8],%g3 + add %o0,-4,%o0 + add %o1,-4,%o1 + addcc %g4,-1,%g4 + sll %g2,%o3,%o4 + srl %g3,%o5,%g1 + mov %g3,%g2 + or %o4,%g1,%o4 + bne LOC(loop0) + st %o4,[%o0+0] + +LOC(0): tst %o2 + be LOC(end) + nop + +LOC(loop): + ld [%o1-8],%g3 + add %o0,-16,%o0 + addcc %o2,-4,%o2 + sll %g2,%o3,%o4 + srl %g3,%o5,%g1 + + ld [%o1-12],%g2 + sll %g3,%o3,%g4 + or %o4,%g1,%o4 + st %o4,[%o0+12] + srl %g2,%o5,%g1 + + ld [%o1-16],%g3 + sll %g2,%o3,%o4 + or %g4,%g1,%g4 + st %g4,[%o0+8] + srl %g3,%o5,%g1 + + ld [%o1-20],%g2 + sll %g3,%o3,%g4 + or %o4,%g1,%o4 + st %o4,[%o0+4] + srl %g2,%o5,%g1 + + add %o1,-16,%o1 + or %g4,%g1,%g4 + bne LOC(loop) + st %g4,[%o0+0] + +LOC(end): + sll %g2,%o3,%g2 + st %g2,[%o0-4] + retl + ld [%sp+80],%o0 + +END(__mpn_lshift) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/memchr.S b/REORG.TODO/sysdeps/sparc/sparc32/memchr.S new file mode 100644 index 0000000000..d00e2fef46 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/memchr.S @@ -0,0 +1,142 @@ +/* memchr (str, ch, n) -- Return pointer to first occurrence of CH in STR less + than N. + For SPARC v7. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jj@ultra.linux.cz> and + David S. Miller <davem@caip.rutgers.edu>. + This version is developed using the same algorithm as the fast C + version which carries the following introduction: + Based on strlen implementation by Torbjorn Granlund (tege@sics.se), + with help from Dan Sahlin (dan@sics.se) and + commentary by Jim Blandy (jimb@ai.mit.edu); + adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu), + and implemented by Roland McGrath (roland@ai.mit.edu). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + + .text + .align 4 +ENTRY(__memchr) + andcc %o1, 0xff, %o1 + sll %o1, 8, %g6 + andcc %o0, 3, %g0 + or %o1, %g6, %g6 + sll %g6, 16, %o3 + be 10f + or %o3, %g6, %g2 + cmp %o2, 0 + be 9f + sethi %hi(0x80808080), %o4 + ldub [%o0], %g4 + cmp %g4, %o1 + be 1f + add %o0, 1, %o0 + subcc %o2, 1, %o2 + be 9f + andcc %o0, 3, %g0 + be 4f + or %o4, %lo(0x80808080), %o3 + ldub [%o0], %g4 + cmp %g4, %o1 + be 1f + add %o0, 1, %o0 + subcc %o2, 1, %o2 + be 9f + andcc %o0, 3, %g0 + be 5f + sethi %hi(0x01010101), %o5 + ldub [%o0], %g4 + cmp %g4, %o1 + be 1f + add %o0, 1, %o0 + subcc %o2, 1, %o2 + bne,a 7f + and %o2, 3, %g1 + retl + clr %o0 +1: retl + sub %o0, 1, %o0 +10: sethi %hi(0x80808080), %o4 + or %o4, %lo(0x80808080), %o3 +4: sethi %hi(0x01010101), %o5 +5: and %o2, 3, %g1 +7: andcc %o2, 0xfffffffc, %o2 + be 0f + or %o5, %lo(0x01010101), %g6 + ld [%o0], %g4 +6: xor %g4, %g2, %g5 + add %o0, 4, %o0 + sub %g5, %g6, %g5 + andcc %g5, %o3, %g0 + bne 8f + subcc %o2, 4, %o2 + bne,a 6b + ld [%o0], %g4 +0: cmp %g1, 0 +1: be 9f + add %o0, 4, %o0 + ldub [%o0 - 4], %g4 + cmp %g4, %o1 + be 4f + cmp %g1, 1 + be 9f + ldub [%o0 - 3], %g4 + cmp %g4, %o1 + be 3f + cmp %g1, 2 + be 9f + ldub [%o0 - 2], %g4 + cmp %g4, %o1 + be 2f + nop +9: retl + clr %o0 + + /* Check every byte. */ +8: srl %g4, 24, %g5 + and %g5, 0xff, %g5 + cmp %g5, %o1 + be 4f + srl %g4, 16, %g5 + and %g5, 0xff, %g5 + cmp %g5, %o1 + be 3f + srl %g4, 8, %g5 + and %g5, 0xff, %g5 + cmp %g5, %o1 + be 2f + and %g4, 0xff, %g5 + cmp %g5, %o1 + be 1f + cmp %o2, 0 + bne,a 6b + ld [%o0], %g4 + b 1b + cmp %g1, 0 +1: retl + sub %o0, 1, %o0 +2: retl + sub %o0, 2, %o0 +3: retl + sub %o0, 3, %o0 +4: retl + sub %o0, 4, %o0 +END(__memchr) + +weak_alias (__memchr, memchr) +libc_hidden_builtin_def (memchr) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/memcpy.S b/REORG.TODO/sysdeps/sparc/sparc32/memcpy.S new file mode 100644 index 0000000000..da672bd120 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/memcpy.S @@ -0,0 +1,653 @@ +/* Copy SIZE bytes from SRC to DEST. + For SPARC v7. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@caip.rutgers.edu>, + Eddie C. Dost <ecd@skynet.be> 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 <sysdep.h> + +/* Both these macros have to start with exactly the same insn */ +#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \ + ldd [%src + offset + 0x00], %t0; \ + ldd [%src + offset + 0x08], %t2; \ + ldd [%src + offset + 0x10], %t4; \ + ldd [%src + offset + 0x18], %t6; \ + st %t0, [%dst + offset + 0x00]; \ + st %t1, [%dst + offset + 0x04]; \ + st %t2, [%dst + offset + 0x08]; \ + st %t3, [%dst + offset + 0x0c]; \ + st %t4, [%dst + offset + 0x10]; \ + st %t5, [%dst + offset + 0x14]; \ + st %t6, [%dst + offset + 0x18]; \ + st %t7, [%dst + offset + 0x1c]; + +#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \ + ldd [%src + offset + 0x00], %t0; \ + ldd [%src + offset + 0x08], %t2; \ + ldd [%src + offset + 0x10], %t4; \ + ldd [%src + offset + 0x18], %t6; \ + std %t0, [%dst + offset + 0x00]; \ + std %t2, [%dst + offset + 0x08]; \ + std %t4, [%dst + offset + 0x10]; \ + std %t6, [%dst + offset + 0x18]; + +#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \ + ldd [%src - offset - 0x10], %t0; \ + ldd [%src - offset - 0x08], %t2; \ + st %t0, [%dst - offset - 0x10]; \ + st %t1, [%dst - offset - 0x0c]; \ + st %t2, [%dst - offset - 0x08]; \ + st %t3, [%dst - offset - 0x04]; + +#define MOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) \ + ldd [%src - offset - 0x10], %t0; \ + ldd [%src - offset - 0x08], %t2; \ + std %t0, [%dst - offset - 0x10]; \ + std %t2, [%dst - offset - 0x08]; + +#define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \ + ldub [%src - offset - 0x02], %t0; \ + ldub [%src - offset - 0x01], %t1; \ + stb %t0, [%dst - offset - 0x02]; \ + stb %t1, [%dst - offset - 0x01]; + +#define SMOVE_CHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \ + ldd [%src + offset + 0x00], %t0; \ + ldd [%src + offset + 0x08], %t2; \ + srl %t0, shir, %t5; \ + srl %t1, shir, %t6; \ + sll %t0, shil, %t0; \ + or %t5, %prev, %t5; \ + sll %t1, shil, %prev; \ + or %t6, %t0, %t0; \ + srl %t2, shir, %t1; \ + srl %t3, shir, %t6; \ + sll %t2, shil, %t2; \ + or %t1, %prev, %t1; \ + std %t4, [%dst + offset + offset2 - 0x04]; \ + std %t0, [%dst + offset + offset2 + 0x04]; \ + sll %t3, shil, %prev; \ + or %t6, %t2, %t4; + +#define SMOVE_ALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \ + ldd [%src + offset + 0x00], %t0; \ + ldd [%src + offset + 0x08], %t2; \ + srl %t0, shir, %t4; \ + srl %t1, shir, %t5; \ + sll %t0, shil, %t6; \ + or %t4, %prev, %t0; \ + sll %t1, shil, %prev; \ + or %t5, %t6, %t1; \ + srl %t2, shir, %t4; \ + srl %t3, shir, %t5; \ + sll %t2, shil, %t6; \ + or %t4, %prev, %t2; \ + sll %t3, shil, %prev; \ + or %t5, %t6, %t3; \ + std %t0, [%dst + offset + offset2 + 0x00]; \ + std %t2, [%dst + offset + offset2 + 0x08]; + + .text +ENTRY(__mempcpy) + add %o0, %o2, %g1 + ba 101f + st %g1, [%sp + 64] +END(__mempcpy) + + .align 4 +ENTRY(memcpy) /* %o0=dst %o1=src %o2=len */ + st %o0, [%sp + 64] +101: + sub %o0, %o1, %o4 +9: andcc %o4, 3, %o5 +0: bne 86f + cmp %o2, 15 + + bleu 90f + andcc %o1, 3, %g0 + + be 78f + andcc %o1, 4, %g0 + + andcc %o1, 1, %g0 + be 4f + andcc %o1, 2, %g0 + + ldub [%o1], %g2 + add %o1, 1, %o1 + stb %g2, [%o0] + sub %o2, 1, %o2 + bne 77f + add %o0, 1, %o0 +4: lduh [%o1], %g2 + add %o1, 2, %o1 + sth %g2, [%o0] + sub %o2, 2, %o2 + add %o0, 2, %o0 + +77: andcc %o1, 4, %g0 +78: be 2f + mov %o2, %g1 + + ld [%o1], %o4 + sub %g1, 4, %g1 + st %o4, [%o0] + add %o1, 4, %o1 + add %o0, 4, %o0 +2: andcc %g1, 0xffffff80, %g6 + be 3f + andcc %o0, 4, %g0 + + be 82f + 4 +5: MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) + MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) + MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) + MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) + subcc %g6, 128, %g6 + add %o1, 128, %o1 + bne 5b + add %o0, 128, %o0 +3: andcc %g1, 0x70, %g6 + be 80f + andcc %g1, 8, %g0 + + srl %g6, 1, %o4 + mov %o7, %g2 + add %g6, %o4, %o4 + add %o1, %g6, %o1 +104: call 100f + add %o0, %g6, %o0 + jmpl %o5 + (80f - 104b), %g0 + mov %g2, %o7 + +79: MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5) + MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5) + MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5) + MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5) + MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5) + MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5) + MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5) + +80: be 81f + andcc %g1, 4, %g0 + + ldd [%o1], %g2 + add %o0, 8, %o0 + st %g2, [%o0 - 0x08] + add %o1, 8, %o1 + st %g3, [%o0 - 0x04] + +81: be 1f + andcc %g1, 2, %g0 + + ld [%o1], %g2 + add %o1, 4, %o1 + st %g2, [%o0] + add %o0, 4, %o0 +1: be 1f + andcc %g1, 1, %g0 + + lduh [%o1], %g2 + add %o1, 2, %o1 + sth %g2, [%o0] + add %o0, 2, %o0 +1: be 1f + nop + + ldub [%o1], %g2 + stb %g2, [%o0] +1: retl + ld [%sp + 64], %o0 + +82: /* ldd_std */ + MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) + MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) + MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) + MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) + subcc %g6, 128, %g6 + add %o1, 128, %o1 + bne 82b + add %o0, 128, %o0 + + andcc %g1, 0x70, %g6 + be 84f + andcc %g1, 8, %g0 + + mov %o7, %g2 +111: call 110f + add %o1, %g6, %o1 + mov %g2, %o7 + jmpl %o5 + (84f - 111b), %g0 + add %o0, %g6, %o0 + +83: MOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3, g4, g5) + MOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3, g4, g5) + MOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3, g4, g5) + MOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5) + MOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5) + MOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5) + MOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5) + +84: be 85f + andcc %g1, 4, %g0 + + ldd [%o1], %g2 + add %o0, 8, %o0 + std %g2, [%o0 - 0x08] + add %o1, 8, %o1 +85: be 1f + andcc %g1, 2, %g0 + + ld [%o1], %g2 + add %o1, 4, %o1 + st %g2, [%o0] + add %o0, 4, %o0 +1: be 1f + andcc %g1, 1, %g0 + + lduh [%o1], %g2 + add %o1, 2, %o1 + sth %g2, [%o0] + add %o0, 2, %o0 +1: be 1f + nop + + ldub [%o1], %g2 + stb %g2, [%o0] +1: retl + ld [%sp + 64], %o0 + +86: cmp %o2, 6 + bleu 88f + + cmp %o2, 256 + bcc 87f + + andcc %o0, 3, %g0 + be 61f + andcc %o0, 1, %g0 + be 60f + andcc %o0, 2, %g0 + + ldub [%o1], %g5 + add %o1, 1, %o1 + stb %g5, [%o0] + sub %o2, 1, %o2 + bne 61f + add %o0, 1, %o0 +60: ldub [%o1], %g3 + add %o1, 2, %o1 + stb %g3, [%o0] + sub %o2, 2, %o2 + ldub [%o1 - 1], %g3 + add %o0, 2, %o0 + stb %g3, [%o0 - 1] +61: and %o1, 3, %g2 + and %o2, 0xc, %g3 + and %o1, -4, %o1 + cmp %g3, 4 + sll %g2, 3, %g4 + mov 32, %g2 + be 4f + sub %g2, %g4, %g6 + + blu 3f + cmp %g3, 0x8 + + be 2f + srl %o2, 2, %g3 + + ld [%o1], %o3 + add %o0, -8, %o0 + ld [%o1 + 4], %o4 + b 8f + add %g3, 1, %g3 +2: ld [%o1], %o4 + add %o0, -12, %o0 + ld [%o1 + 4], %o5 + add %g3, 2, %g3 + b 9f + add %o1, -4, %o1 +3: ld [%o1], %g1 + add %o0, -4, %o0 + ld [%o1 + 4], %o3 + srl %o2, 2, %g3 + b 7f + add %o1, 4, %o1 +4: ld [%o1], %o5 + cmp %o2, 7 + ld [%o1 + 4], %g1 + srl %o2, 2, %g3 + bleu 10f + add %o1, 8, %o1 + + ld [%o1], %o3 + add %g3, -1, %g3 +5: sll %o5, %g4, %g2 + srl %g1, %g6, %g5 + or %g2, %g5, %g2 + st %g2, [%o0] +7: ld [%o1 + 4], %o4 + sll %g1, %g4, %g2 + srl %o3, %g6, %g5 + or %g2, %g5, %g2 + st %g2, [%o0 + 4] +8: ld [%o1 + 8], %o5 + sll %o3, %g4, %g2 + srl %o4, %g6, %g5 + or %g2, %g5, %g2 + st %g2, [%o0 + 8] +9: ld [%o1 + 12], %g1 + sll %o4, %g4, %g2 + srl %o5, %g6, %g5 + addcc %g3, -4, %g3 + or %g2, %g5, %g2 + add %o1, 16, %o1 + st %g2, [%o0 + 12] + add %o0, 16, %o0 + bne,a 5b + ld [%o1], %o3 +10: sll %o5, %g4, %g2 + srl %g1, %g6, %g5 + srl %g6, 3, %g3 + or %g2, %g5, %g2 + sub %o1, %g3, %o1 + andcc %o2, 2, %g0 + st %g2, [%o0] + be 1f + andcc %o2, 1, %g0 + + ldub [%o1], %g2 + add %o1, 2, %o1 + stb %g2, [%o0 + 4] + add %o0, 2, %o0 + ldub [%o1 - 1], %g2 + stb %g2, [%o0 + 3] +1: be 1f + nop + ldub [%o1], %g2 + stb %g2, [%o0 + 4] +1: retl + ld [%sp + 64], %o0 + +87: andcc %o1, 3, %g0 + be 3f + andcc %o1, 1, %g0 + + be 4f + andcc %o1, 2, %g0 + + ldub [%o1], %g2 + add %o1, 1, %o1 + stb %g2, [%o0] + sub %o2, 1, %o2 + bne 3f + add %o0, 1, %o0 +4: lduh [%o1], %g2 + add %o1, 2, %o1 + srl %g2, 8, %g3 + sub %o2, 2, %o2 + stb %g3, [%o0] + add %o0, 2, %o0 + stb %g2, [%o0 - 1] +3: andcc %o1, 4, %g0 + + bne 2f + cmp %o5, 1 + + ld [%o1], %o4 + srl %o4, 24, %g2 + stb %g2, [%o0] + srl %o4, 16, %g3 + stb %g3, [%o0 + 1] + srl %o4, 8, %g2 + stb %g2, [%o0 + 2] + sub %o2, 4, %o2 + stb %o4, [%o0 + 3] + add %o1, 4, %o1 + add %o0, 4, %o0 +2: be 33f + cmp %o5, 2 + be 32f + sub %o2, 4, %o2 +31: ld [%o1], %g2 + add %o1, 4, %o1 + srl %g2, 24, %g3 + and %o0, 7, %g5 + stb %g3, [%o0] + cmp %g5, 7 + sll %g2, 8, %g1 + add %o0, 4, %o0 + be 41f + and %o2, 0xffffffc0, %o3 + ld [%o0 - 7], %o4 +4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3) + SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3) + SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3) + SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3) + subcc %o3, 64, %o3 + add %o1, 64, %o1 + bne 4b + add %o0, 64, %o0 + + andcc %o2, 0x30, %o3 + be,a 1f + srl %g1, 16, %g2 +4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3) + subcc %o3, 16, %o3 + add %o1, 16, %o1 + bne 4b + add %o0, 16, %o0 + + srl %g1, 16, %g2 +1: st %o4, [%o0 - 7] + sth %g2, [%o0 - 3] + srl %g1, 8, %g4 + b 88f + stb %g4, [%o0 - 1] +32: ld [%o1], %g2 + add %o1, 4, %o1 + srl %g2, 16, %g3 + and %o0, 7, %g5 + sth %g3, [%o0] + cmp %g5, 6 + sll %g2, 16, %g1 + add %o0, 4, %o0 + be 42f + and %o2, 0xffffffc0, %o3 + ld [%o0 - 6], %o4 +4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2) + SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2) + SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2) + SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2) + subcc %o3, 64, %o3 + add %o1, 64, %o1 + bne 4b + add %o0, 64, %o0 + + andcc %o2, 0x30, %o3 + be,a 1f + srl %g1, 16, %g2 +4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2) + subcc %o3, 16, %o3 + add %o1, 16, %o1 + bne 4b + add %o0, 16, %o0 + + srl %g1, 16, %g2 +1: st %o4, [%o0 - 6] + b 88f + sth %g2, [%o0 - 2] +33: ld [%o1], %g2 + sub %o2, 4, %o2 + srl %g2, 24, %g3 + and %o0, 7, %g5 + stb %g3, [%o0] + cmp %g5, 5 + srl %g2, 8, %g4 + sll %g2, 24, %g1 + sth %g4, [%o0 + 1] + add %o1, 4, %o1 + be 43f + and %o2, 0xffffffc0, %o3 + + ld [%o0 - 1], %o4 + add %o0, 4, %o0 +4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1) + SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1) + SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1) + SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1) + subcc %o3, 64, %o3 + add %o1, 64, %o1 + bne 4b + add %o0, 64, %o0 + + andcc %o2, 0x30, %o3 + be,a 1f + srl %g1, 24, %g2 +4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1) + subcc %o3, 16, %o3 + add %o1, 16, %o1 + bne 4b + add %o0, 16, %o0 + + srl %g1, 24, %g2 +1: st %o4, [%o0 - 5] + b 88f + stb %g2, [%o0 - 1] +41: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3) + SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3) + SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3) + SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3) + subcc %o3, 64, %o3 + add %o1, 64, %o1 + bne 41b + add %o0, 64, %o0 + + andcc %o2, 0x30, %o3 + be,a 1f + srl %g1, 16, %g2 +4: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3) + subcc %o3, 16, %o3 + add %o1, 16, %o1 + bne 4b + add %o0, 16, %o0 + + srl %g1, 16, %g2 +1: sth %g2, [%o0 - 3] + srl %g1, 8, %g4 + b 88f + stb %g4, [%o0 - 1] +43: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3) + SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3) + SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3) + SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3) + subcc %o3, 64, %o3 + add %o1, 64, %o1 + bne 43b + add %o0, 64, %o0 + + andcc %o2, 0x30, %o3 + be,a 1f + srl %g1, 24, %g2 +4: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3) + subcc %o3, 16, %o3 + add %o1, 16, %o1 + bne 4b + add %o0, 16, %o0 + + srl %g1, 24, %g2 +1: stb %g2, [%o0 + 3] + b 88f + add %o0, 4, %o0 +42: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2) + SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2) + SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2) + SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2) + subcc %o3, 64, %o3 + add %o1, 64, %o1 + bne 42b + add %o0, 64, %o0 + + andcc %o2, 0x30, %o3 + be,a 1f + srl %g1, 16, %g2 +4: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2) + subcc %o3, 16, %o3 + add %o1, 16, %o1 + bne 4b + add %o0, 16, %o0 + + srl %g1, 16, %g2 +1: sth %g2, [%o0 - 2] + + /* Fall through */ + +88: and %o2, 0xe, %o3 + mov %o7, %g2 + sll %o3, 3, %o4 + add %o0, %o3, %o0 +106: call 100f + add %o1, %o3, %o1 + mov %g2, %o7 + jmpl %o5 + (89f - 106b), %g0 + andcc %o2, 1, %g0 + + MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3) + MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3) + MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3) + MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3) + MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3) + MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3) + MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3) + +89: be 1f + nop + + ldub [%o1], %g2 + stb %g2, [%o0] +1: retl + ld [%sp + 64], %o0 + +90: bne 88b + andcc %o2, 8, %g0 + + be 1f + andcc %o2, 4, %g0 + + ld [%o1 + 0x00], %g2 + ld [%o1 + 0x04], %g3 + add %o1, 8, %o1 + st %g2, [%o0 + 0x00] + st %g3, [%o0 + 0x04] + add %o0, 8, %o0 +1: b 81b + mov %o2, %g1 + +100: retl + sub %o7, %o4, %o5 +110: retl + sub %o7, %g6, %o5 +END(memcpy) + +libc_hidden_builtin_def (memcpy) + +libc_hidden_def (__mempcpy) +weak_alias (__mempcpy, mempcpy) +libc_hidden_builtin_def (mempcpy) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/memset.S b/REORG.TODO/sysdeps/sparc/sparc32/memset.S new file mode 100644 index 0000000000..db44115047 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/memset.S @@ -0,0 +1,154 @@ +/* Set a block of memory to some byte value. + For SPARC v7. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@caip.rutgers.edu> 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 <sysdep.h> + + /* Store 64 bytes at (BASE + OFFSET) using value SOURCE. */ +#define ZERO_BIG_BLOCK(base, offset, source) \ + std source, [base + offset + 0x00]; \ + std source, [base + offset + 0x08]; \ + std source, [base + offset + 0x10]; \ + std source, [base + offset + 0x18]; \ + std source, [base + offset + 0x20]; \ + std source, [base + offset + 0x28]; \ + std source, [base + offset + 0x30]; \ + std source, [base + offset + 0x38]; + +#define ZERO_LAST_BLOCKS(base, offset, source) \ + std source, [base - offset - 0x38]; \ + std source, [base - offset - 0x30]; \ + std source, [base - offset - 0x28]; \ + std source, [base - offset - 0x20]; \ + std source, [base - offset - 0x18]; \ + std source, [base - offset - 0x10]; \ + std source, [base - offset - 0x08]; \ + std source, [base - offset - 0x00]; + + .text + .align 4 +ENTRY(__bzero) + b 1f + mov %g0, %g3 + +3: cmp %o2, 3 + be 2f + stb %g3, [%o0] + + cmp %o2, 2 + be 2f + stb %g3, [%o0 + 0x01] + + stb %g3, [%o0 + 0x02] +2: sub %o2, 4, %o2 + add %o1, %o2, %o1 + b 4f + sub %o0, %o2, %o0 +END(__bzero) + +ENTRY(memset) + and %o1, 0xff, %g3 + sll %g3, 8, %g2 + or %g3, %g2, %g3 + sll %g3, 16, %g2 + or %g3, %g2, %g3 + orcc %o2, %g0, %o1 +1: cmp %o1, 7 + bleu 7f + mov %o0, %g1 + + andcc %o0, 3, %o2 + bne 3b +4: andcc %o0, 4, %g0 + + be 2f + mov %g3, %g2 + + st %g3, [%o0] + sub %o1, 4, %o1 + add %o0, 4, %o0 +2: andcc %o1, 0xffffff80, %o3 + be 9f + andcc %o1, 0x78, %o2 +4: ZERO_BIG_BLOCK (%o0, 0x00, %g2) + subcc %o3, 128, %o3 + ZERO_BIG_BLOCK (%o0, 0x40, %g2) + bne 4b + add %o0, 128, %o0 + + orcc %o2, %g0, %g0 +9: be 6f + andcc %o1, 7, %o1 + + mov %o7, %g4 +101: call 100f + srl %o2, 1, %o3 + mov %g4, %o7 + jmpl %o4 + (20f + 64 - 101b), %g0 + add %o0, %o2, %o0 + +100: retl + sub %o7, %o3, %o4 + +20: ZERO_LAST_BLOCKS(%o0, 0x48, %g2) + ZERO_LAST_BLOCKS(%o0, 0x08, %g2) + +6: be 8f + andcc %o1, 4, %g0 + be 1f + andcc %o1, 2, %g0 + st %g3, [%o0] + add %o0, 4, %o0 +1: be 1f + andcc %o1, 1, %g0 + sth %g3, [%o0] + add %o0, 2, %o0 +1: bne,a 8f + stb %g3, [%o0] +8: retl + mov %g1, %o0 +7: orcc %o1, 0, %g0 + be 0f + subcc %o1, 1, %o1 + stb %g3, [%o0] + be 0f + subcc %o1, 1, %o1 + stb %g3, [%o0 + 1] + be 0f + subcc %o1, 1, %o1 + stb %g3, [%o0 + 2] + be 0f + subcc %o1, 1, %o1 + stb %g3, [%o0 + 3] + be 0f + subcc %o1, 1, %o1 + stb %g3, [%o0 + 4] + be 0f + subcc %o1, 1, %o1 + stb %g3, [%o0 + 5] + be 0f + subcc %o1, 1, %o1 + stb %g3, [%o0 + 6] +0: retl + nop +END(memset) +libc_hidden_builtin_def (memset) + +weak_alias (__bzero, bzero) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/mul_1.S b/REORG.TODO/sysdeps/sparc/sparc32/mul_1.S new file mode 100644 index 0000000000..8f7cd752a4 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/mul_1.S @@ -0,0 +1,198 @@ +! SPARC __mpn_mul_1 -- Multiply a limb vector with a limb and store +! the result 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; see the file COPYING.LIB. If not, +! see <http://www.gnu.org/licenses/>. + + +! INPUT PARAMETERS +! RES_PTR o0 +! S1_PTR o1 +! SIZE o2 +! S2_LIMB o3 + +! ADD CODE FOR SMALL MULTIPLIERS! +!1: ld +! st +! +!2: ld ,a +! addxcc a,a,x +! st x, +! +!3_unrolled: +! ld ,a +! addxcc a,a,x1 ! 2a + cy +! addx %g0,%g0,x2 +! addcc a,x1,x ! 3a + c +! st x, +! +! ld ,a +! addxcc a,a,y1 +! addx %g0,%g0,y2 +! addcc a,y1,x +! st x, +! +!4_unrolled: +! ld ,a +! srl a,2,x1 ! 4a +! addxcc y2,x1,x +! sll a,30,x2 +! st x, +! +! ld ,a +! srl a,2,y1 +! addxcc x2,y1,y +! sll a,30,y2 +! st x, +! +!5_unrolled: +! ld ,a +! srl a,2,x1 ! 4a +! addxcc a,x1,x ! 5a + c +! sll a,30,x2 +! addx %g0,x2,x2 +! st x, +! +! ld ,a +! srl a,2,y1 +! addxcc a,y1,x +! sll a,30,y2 +! addx %g0,y2,y2 +! st x, +! +!8_unrolled: +! ld ,a +! srl a,3,x1 ! 8a +! addxcc y2,x1,x +! sll a,29,x2 +! st x, +! +! ld ,a +! srl a,3,y1 +! addxcc x2,y1,y +! sll a,29,y2 +! st x, + +#include <sysdep.h> + +ENTRY(__mpn_mul_1) + ! Make S1_PTR and RES_PTR point at the end of their blocks + ! and put (- 4 x SIZE) in index/loop counter. + sll %o2,2,%o2 + add %o0,%o2,%o4 ! RES_PTR in o4 since o0 is retval + add %o1,%o2,%o1 + sub %g0,%o2,%o2 + + cmp %o3,0xfff + bgu LOC(large) + nop + + ld [%o1+%o2],%o5 + mov 0,%o0 + b LOC(0) + add %o4,-4,%o4 +LOC(loop0): + st %g1,[%o4+%o2] +LOC(0): wr %g0,%o3,%y + sra %o5,31,%g2 + and %o3,%g2,%g2 + andcc %g1,0,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,0,%g1 + sra %g1,20,%g4 + sll %g1,12,%g1 + rd %y,%g3 + srl %g3,20,%g3 + or %g1,%g3,%g1 + + addcc %g1,%o0,%g1 + addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb + addcc %o2,4,%o2 ! loop counter + bne,a LOC(loop0) + ld [%o1+%o2],%o5 + + retl + st %g1,[%o4+%o2] + + +LOC(large): + ld [%o1+%o2],%o5 + mov 0,%o0 + sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0 + b LOC(1) + add %o4,-4,%o4 +LOC(loop): + st %g3,[%o4+%o2] +LOC(1): wr %g0,%o5,%y + and %o5,%g4,%g2 ! g2 = S1_LIMB iff S2_LIMB < 0, else 0 + andcc %g0,%g0,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%g0,%g1 + rd %y,%g3 + addcc %g3,%o0,%g3 + addx %g2,%g1,%o0 ! add sign-compensation and cy to hi limb + addcc %o2,4,%o2 ! loop counter + bne,a LOC(loop) + ld [%o1+%o2],%o5 + + retl + st %g3,[%o4+%o2] + +END(__mpn_mul_1) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/pthread_barrier_wait.c b/REORG.TODO/sysdeps/sparc/sparc32/pthread_barrier_wait.c new file mode 100644 index 0000000000..e5ef911f62 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/pthread_barrier_wait.c @@ -0,0 +1 @@ +#error No support for pthread barriers on pre-v9 sparc. diff --git a/REORG.TODO/sysdeps/sparc/sparc32/pthread_spin_lock.S b/REORG.TODO/sysdeps/sparc/sparc32/pthread_spin_lock.S new file mode 100644 index 0000000000..7d57c525b1 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/pthread_spin_lock.S @@ -0,0 +1,32 @@ +/* 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/>. */ + +#include <sysdep.h> + + .text +ENTRY(pthread_spin_lock) +1: ldstub [%o0], %g1 + orcc %g1, 0x0, %g0 + bne,a 2f + ldub [%o0], %g1 + retl + mov 0, %o0 +2: orcc %g1, 0x0, %g0 + bne,a 2b + ldub [%o0], %g1 + ba,a 1b +END(pthread_spin_lock) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/pthread_spin_trylock.S b/REORG.TODO/sysdeps/sparc/sparc32/pthread_spin_trylock.S new file mode 100644 index 0000000000..061b37a834 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/pthread_spin_trylock.S @@ -0,0 +1,29 @@ +/* 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/>. */ + +#include <sysdep.h> +#include <pthread-errnos.h> + + .text +ENTRY(pthread_spin_trylock) + ldstub [%o0], %o0 + cmp %o0, 0 + bne,a 1f + mov EBUSY, %o0 +1: retl + nop +END(pthread_spin_trylock) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/pthreaddef.h b/REORG.TODO/sysdeps/sparc/sparc32/pthreaddef.h new file mode 100644 index 0000000000..720e183fde --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/pthreaddef.h @@ -0,0 +1,33 @@ +/* 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/>. */ + +/* 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 (stack_pointer + (2 * 64)) +register char *stack_pointer __asm__("%sp"); diff --git a/REORG.TODO/sysdeps/sparc/sparc32/rem.S b/REORG.TODO/sysdeps/sparc/sparc32/rem.S new file mode 100644 index 0000000000..349d7c0115 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/rem.S @@ -0,0 +1,363 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * .rem name of function to generate + * rem rem=div => %o0 / %o1; rem=rem => %o0 % %o1 + * true true=true => signed; true=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top decade of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + + + +#include <sysdep.h> +#include <sys/trap.h> + +ENTRY(.rem) + ! compute sign of result; if neither is negative, no problem + orcc %o1, %o0, %g0 ! either negative? + bge 2f ! no, go do the divide + mov %o0, %g3 ! sign of remainder matches %o0 + tst %o1 + bge 1f + tst %o0 + ! %o1 is definitely negative; %o0 might also be negative + bge 2f ! if %o0 not negative... + sub %g0, %o1, %o1 ! in any case, make %o1 nonneg +1: ! %o0 is negative, %o1 is nonnegative + sub %g0, %o0, %o0 ! make %o0 nonnegative +2: + + ! Ready to divide. Compute size of quotient; scale comparand. + orcc %o1, %g0, %o5 + bne 1f + mov %o0, %o3 + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp %o3, %o5 ! if %o1 exceeds %o0, done + blu LOC(got_result) ! (and algorithm fails otherwise) + clr %o2 + sethi %hi(1 << (32 - 4 - 1)), %g1 + cmp %o3, %g1 + blu LOC(not_really_big) + clr %o4 + + ! Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R. + 1: + cmp %o5, %g1 + bgeu 3f + mov 1, %g2 + sll %o5, 4, %o5 + b 1b + add %o4, 1, %o4 + + ! Now compute %g2. + 2: addcc %o5, %o5, %o5 + bcc LOC(not_too_big) + add %g2, 1, %g2 + + ! We get here if the %o1 overflowed while shifting. + ! This means that %o3 has the high-order bit set. + ! Restore %o5 and subtract from %o3. + sll %g1, 4, %g1 ! high order bit + srl %o5, 1, %o5 ! rest of %o5 + add %o5, %g1, %o5 + b LOC(do_single_div) + sub %g2, 1, %g2 + + LOC(not_too_big): + 3: cmp %o5, %o3 + blu 2b + nop + be LOC(do_single_div) + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! %o5 > %o3: went too far: back up 1 step + ! srl %o5, 1, %o5 + ! dec %g2 + ! do single-bit divide steps + ! + ! We have to be careful here. We know that %o3 >= %o5, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + LOC(do_single_div): + subcc %g2, 1, %g2 + bl LOC(end_regular_divide) + nop + sub %o3, %o5, %o3 + mov 1, %o2 + b LOC(end_single_divloop) + nop + LOC(single_divloop): + sll %o2, 1, %o2 + bl 1f + srl %o5, 1, %o5 + ! %o3 >= 0 + sub %o3, %o5, %o3 + b 2f + add %o2, 1, %o2 + 1: ! %o3 < 0 + add %o3, %o5, %o3 + sub %o2, 1, %o2 + 2: + LOC(end_single_divloop): + subcc %g2, 1, %g2 + bge LOC(single_divloop) + tst %o3 + b,a LOC(end_regular_divide) + +LOC(not_really_big): +1: + sll %o5, 4, %o5 + cmp %o5, %o3 + bleu 1b + addcc %o4, 1, %o4 + be LOC(got_result) + sub %o4, 1, %o4 + + tst %o3 ! set up for initial iteration +LOC(divloop): + sll %o2, 4, %o2 + ! depth 1, accumulated bits 0 + bl LOC(1.16) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 2, accumulated bits 1 + bl LOC(2.17) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits 3 + bl LOC(3.19) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 7 + bl LOC(4.23) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (7*2+1), %o2 + +LOC(4.23): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (7*2-1), %o2 + + +LOC(3.19): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 5 + bl LOC(4.21) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (5*2+1), %o2 + +LOC(4.21): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (5*2-1), %o2 + + + +LOC(2.17): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits 1 + bl LOC(3.17) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 3 + bl LOC(4.19) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (3*2+1), %o2 + +LOC(4.19): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (3*2-1), %o2 + + +LOC(3.17): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 1 + bl LOC(4.17) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (1*2+1), %o2 + +LOC(4.17): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (1*2-1), %o2 + + + + +LOC(1.16): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 2, accumulated bits -1 + bl LOC(2.15) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits -1 + bl LOC(3.15) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -1 + bl LOC(4.15) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2+1), %o2 + +LOC(4.15): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2-1), %o2 + + +LOC(3.15): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -3 + bl LOC(4.13) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2+1), %o2 + +LOC(4.13): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2-1), %o2 + + + +LOC(2.15): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits -3 + bl LOC(3.13) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -5 + bl LOC(4.11) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2+1), %o2 + +LOC(4.11): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2-1), %o2 + + +LOC(3.13): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -7 + bl LOC(4.9) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2+1), %o2 + +LOC(4.9): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2-1), %o2 + + + + + 9: +LOC(end_regular_divide): + subcc %o4, 1, %o4 + bge LOC(divloop) + tst %o3 + bl,a LOC(got_result) + ! non-restoring fixup here (one instruction only!) + add %o3, %o1, %o3 + + +LOC(got_result): + ! check to see if answer should be < 0 + tst %g3 + bl,a 1f + sub %g0, %o3, %o3 +1: + retl + mov %o3, %o0 + +END(.rem) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/rshift.S b/REORG.TODO/sysdeps/sparc/sparc32/rshift.S new file mode 100644 index 0000000000..4185044168 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/rshift.S @@ -0,0 +1,93 @@ +! sparc __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; see the file COPYING.LIB. If not, +! see <http://www.gnu.org/licenses/>. + + +! INPUT PARAMETERS +! RES_PTR %o0 +! SRC_PTR %o1 +! SIZE %o2 +! CNT %o3 + +#include <sysdep.h> + +ENTRY(__mpn_rshift) + ld [%o1],%g2 ! load first limb + sub %g0,%o3,%o5 ! negate shift count + add %o2,-1,%o2 + andcc %o2,4-1,%g4 ! number of limbs in first loop + sll %g2,%o5,%g1 ! compute function result + be LOC(0) ! if multiple of 4 limbs, skip first loop + st %g1,[%sp+80] + + sub %o2,%g4,%o2 ! adjust count for main loop + +LOC(loop0): + ld [%o1+4],%g3 + add %o0,4,%o0 + add %o1,4,%o1 + addcc %g4,-1,%g4 + srl %g2,%o3,%o4 + sll %g3,%o5,%g1 + mov %g3,%g2 + or %o4,%g1,%o4 + bne LOC(loop0) + st %o4,[%o0-4] + +LOC(0): tst %o2 + be LOC(end) + nop + +LOC(loop): + ld [%o1+4],%g3 + add %o0,16,%o0 + addcc %o2,-4,%o2 + srl %g2,%o3,%o4 + sll %g3,%o5,%g1 + + ld [%o1+8],%g2 + srl %g3,%o3,%g4 + or %o4,%g1,%o4 + st %o4,[%o0-16] + sll %g2,%o5,%g1 + + ld [%o1+12],%g3 + srl %g2,%o3,%o4 + or %g4,%g1,%g4 + st %g4,[%o0-12] + sll %g3,%o5,%g1 + + ld [%o1+16],%g2 + srl %g3,%o3,%g4 + or %o4,%g1,%o4 + st %o4,[%o0-8] + sll %g2,%o5,%g1 + + add %o1,16,%o1 + or %g4,%g1,%g4 + bne LOC(loop) + st %g4,[%o0-4] + +LOC(end): + srl %g2,%o3,%g2 + st %g2,[%o0-0] + retl + ld [%sp+80],%o0 + +END(__mpn_rshift) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sdiv.S b/REORG.TODO/sysdeps/sparc/sparc32/sdiv.S new file mode 100644 index 0000000000..d1d4ee31f8 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sdiv.S @@ -0,0 +1,363 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * .div name of function to generate + * div div=div => %o0 / %o1; div=rem => %o0 % %o1 + * true true=true => signed; true=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top decade of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + + + +#include <sysdep.h> +#include <sys/trap.h> + +ENTRY(.div) + ! compute sign of result; if neither is negative, no problem + orcc %o1, %o0, %g0 ! either negative? + bge 2f ! no, go do the divide + xor %o1, %o0, %g3 ! compute sign in any case + tst %o1 + bge 1f + tst %o0 + ! %o1 is definitely negative; %o0 might also be negative + bge 2f ! if %o0 not negative... + sub %g0, %o1, %o1 ! in any case, make %o1 nonneg +1: ! %o0 is negative, %o1 is nonnegative + sub %g0, %o0, %o0 ! make %o0 nonnegative +2: + + ! Ready to divide. Compute size of quotient; scale comparand. + orcc %o1, %g0, %o5 + bne 1f + mov %o0, %o3 + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp %o3, %o5 ! if %o1 exceeds %o0, done + blu LOC(got_result) ! (and algorithm fails otherwise) + clr %o2 + sethi %hi(1 << (32 - 4 - 1)), %g1 + cmp %o3, %g1 + blu LOC(not_really_big) + clr %o4 + + ! Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R. + 1: + cmp %o5, %g1 + bgeu 3f + mov 1, %g2 + sll %o5, 4, %o5 + b 1b + add %o4, 1, %o4 + + ! Now compute %g2. + 2: addcc %o5, %o5, %o5 + bcc LOC(not_too_big) + add %g2, 1, %g2 + + ! We get here if the %o1 overflowed while shifting. + ! This means that %o3 has the high-order bit set. + ! Restore %o5 and subtract from %o3. + sll %g1, 4, %g1 ! high order bit + srl %o5, 1, %o5 ! rest of %o5 + add %o5, %g1, %o5 + b LOC(do_single_div) + sub %g2, 1, %g2 + + LOC(not_too_big): + 3: cmp %o5, %o3 + blu 2b + nop + be LOC(do_single_div) + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! %o5 > %o3: went too far: back up 1 step + ! srl %o5, 1, %o5 + ! dec %g2 + ! do single-bit divide steps + ! + ! We have to be careful here. We know that %o3 >= %o5, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + LOC(do_single_div): + subcc %g2, 1, %g2 + bl LOC(end_regular_divide) + nop + sub %o3, %o5, %o3 + mov 1, %o2 + b LOC(end_single_divloop) + nop + LOC(single_divloop): + sll %o2, 1, %o2 + bl 1f + srl %o5, 1, %o5 + ! %o3 >= 0 + sub %o3, %o5, %o3 + b 2f + add %o2, 1, %o2 + 1: ! %o3 < 0 + add %o3, %o5, %o3 + sub %o2, 1, %o2 + 2: + LOC(end_single_divloop): + subcc %g2, 1, %g2 + bge LOC(single_divloop) + tst %o3 + b,a LOC(end_regular_divide) + +LOC(not_really_big): +1: + sll %o5, 4, %o5 + cmp %o5, %o3 + bleu 1b + addcc %o4, 1, %o4 + be LOC(got_result) + sub %o4, 1, %o4 + + tst %o3 ! set up for initial iteration +LOC(divloop): + sll %o2, 4, %o2 + ! depth 1, accumulated bits 0 + bl LOC(1.16) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 2, accumulated bits 1 + bl LOC(2.17) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits 3 + bl LOC(3.19) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 7 + bl LOC(4.23) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (7*2+1), %o2 + +LOC(4.23): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (7*2-1), %o2 + + +LOC(3.19): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 5 + bl LOC(4.21) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (5*2+1), %o2 + +LOC(4.21): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (5*2-1), %o2 + + + +LOC(2.17): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits 1 + bl LOC(3.17) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 3 + bl LOC(4.19) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (3*2+1), %o2 + +LOC(4.19): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (3*2-1), %o2 + + +LOC(3.17): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 1 + bl LOC(4.17) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (1*2+1), %o2 + +LOC(4.17): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (1*2-1), %o2 + + + + +LOC(1.16): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 2, accumulated bits -1 + bl LOC(2.15) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits -1 + bl LOC(3.15) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -1 + bl LOC(4.15) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2+1), %o2 + +LOC(4.15): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2-1), %o2 + + +LOC(3.15): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -3 + bl LOC(4.13) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2+1), %o2 + +LOC(4.13): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2-1), %o2 + + + +LOC(2.15): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits -3 + bl LOC(3.13) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -5 + bl LOC(4.11) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2+1), %o2 + +LOC(4.11): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2-1), %o2 + + +LOC(3.13): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -7 + bl LOC(4.9) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2+1), %o2 + +LOC(4.9): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2-1), %o2 + + + + + 9: +LOC(end_regular_divide): + subcc %o4, 1, %o4 + bge LOC(divloop) + tst %o3 + bl,a LOC(got_result) + ! non-restoring fixup here (one instruction only!) + sub %o2, 1, %o2 + + +LOC(got_result): + ! check to see if answer should be < 0 + tst %g3 + bl,a 1f + sub %g0, %o2, %o2 +1: + retl + mov %o2, %o0 + +END(.div) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sem_post.c b/REORG.TODO/sysdeps/sparc/sparc32/sem_post.c new file mode 100644 index 0000000000..ae8358dc11 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sem_post.c @@ -0,0 +1,82 @@ +/* sem_post -- post to a POSIX semaphore. Generic futex-using version. + Copyright (C) 2003-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <atomic.h> +#include <errno.h> +#include <sysdep.h> +#include <lowlevellock.h> +#include <internaltypes.h> +#include <semaphore.h> +#include <futex-internal.h> + +#include <shlib-compat.h> + + +/* See sem_wait for an explanation of the algorithm. */ +int +__new_sem_post (sem_t *sem) +{ + struct new_sem *isem = (struct new_sem *) sem; + int private = isem->private; + unsigned int v; + + __sparc32_atomic_do_lock24 (&isem->pad); + + v = isem->value; + if ((v >> SEM_VALUE_SHIFT) == SEM_VALUE_MAX) + { + __sparc32_atomic_do_unlock24 (&isem->pad); + + __set_errno (EOVERFLOW); + return -1; + } + isem->value = v + (1 << SEM_VALUE_SHIFT); + + __sparc32_atomic_do_unlock24 (&isem->pad); + + if ((v & SEM_NWAITERS_MASK) != 0) + futex_wake (&isem->value, 1, private); + + return 0; +} +versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1); + + +#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1) +int +attribute_compat_text_section +__old_sem_post (sem_t *sem) +{ + int *futex = (int *) sem; + + /* We must need to synchronize with consumers of this token, so the atomic + increment must have release MO semantics. */ + atomic_write_barrier (); + (void) atomic_increment_val (futex); + /* We always have to assume it is a shared semaphore. */ + int err = lll_futex_wake (futex, 1, LLL_SHARED); + if (__builtin_expect (err, 0) < 0) + { + __set_errno (-err); + return -1; + } + return 0; +} +compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0); +#endif diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sem_waitcommon.c b/REORG.TODO/sysdeps/sparc/sparc32/sem_waitcommon.c new file mode 100644 index 0000000000..08fd12ce50 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sem_waitcommon.c @@ -0,0 +1,146 @@ +/* sem_waitcommon -- wait on a semaphore, shared code. + Copyright (C) 2003-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <sysdep.h> +#include <futex-internal.h> +#include <internaltypes.h> +#include <semaphore.h> +#include <sys/time.h> + +#include <pthreadP.h> +#include <shlib-compat.h> +#include <atomic.h> + + +static void +__sem_wait_32_finish (struct new_sem *sem); + +static void +__sem_wait_cleanup (void *arg) +{ + struct new_sem *sem = (struct new_sem *) arg; + + __sem_wait_32_finish (sem); +} + +/* Wait until at least one token is available, possibly with a timeout. + This is in a separate function in order to make sure gcc + puts the call site into an exception region, and thus the + cleanups get properly run. TODO still necessary? Other futex_wait + users don't seem to need it. */ +static int +__attribute__ ((noinline)) +do_futex_wait (struct new_sem *sem, const struct timespec *abstime) +{ + int err; + + err = futex_abstimed_wait_cancelable (&sem->value, SEM_NWAITERS_MASK, + abstime, sem->private); + + return err; +} + +/* Fast path: Try to grab a token without blocking. */ +static int +__new_sem_wait_fast (struct new_sem *sem, int definitive_result) +{ + unsigned int v; + int ret = 0; + + __sparc32_atomic_do_lock24(&sem->pad); + + v = sem->value; + if ((v >> SEM_VALUE_SHIFT) == 0) + ret = -1; + else + sem->value = v - (1 << SEM_VALUE_SHIFT); + + __sparc32_atomic_do_unlock24(&sem->pad); + + return ret; +} + +/* Slow path that blocks. */ +static int +__attribute__ ((noinline)) +__new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime) +{ + unsigned int v; + int err = 0; + + __sparc32_atomic_do_lock24(&sem->pad); + + sem->nwaiters++; + + pthread_cleanup_push (__sem_wait_cleanup, sem); + + /* Wait for a token to be available. Retry until we can grab one. */ + v = sem->value; + do + { + if (!(v & SEM_NWAITERS_MASK)) + sem->value = v | SEM_NWAITERS_MASK; + + /* If there is no token, wait. */ + if ((v >> SEM_VALUE_SHIFT) == 0) + { + __sparc32_atomic_do_unlock24(&sem->pad); + + err = do_futex_wait(sem, abstime); + if (err == ETIMEDOUT || err == EINTR) + { + __set_errno (err); + err = -1; + goto error; + } + err = 0; + + __sparc32_atomic_do_lock24(&sem->pad); + + /* We blocked, so there might be a token now. */ + v = sem->value; + } + } + /* If there is no token, we must not try to grab one. */ + while ((v >> SEM_VALUE_SHIFT) == 0); + + sem->value = v - (1 << SEM_VALUE_SHIFT); + + __sparc32_atomic_do_unlock24(&sem->pad); + +error: + pthread_cleanup_pop (0); + + __sem_wait_32_finish (sem); + + return err; +} + +/* Stop being a registered waiter (non-64b-atomics code only). */ +static void +__sem_wait_32_finish (struct new_sem *sem) +{ + __sparc32_atomic_do_lock24(&sem->pad); + + if (--sem->nwaiters == 0) + sem->value &= ~SEM_NWAITERS_MASK; + + __sparc32_atomic_do_unlock24(&sem->pad); +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/setjmp.S b/REORG.TODO/sysdeps/sparc/sparc32/setjmp.S new file mode 100644 index 0000000000..02cf17343b --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/setjmp.S @@ -0,0 +1,59 @@ +/* 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/>. */ + +#include <sysdep.h> +#include <sys/trap.h> + +#include <jmpbuf-offsets.h> + +ENTRY(_setjmp) + b 1f + set 0, %o1 +END(_setjmp) +libc_hidden_def (_setjmp) + +ENTRY(setjmp) + set 1, %o1 +END(setjmp) + +ENTRY (__sigsetjmp) +1: + /* Save our PC, SP and FP. Save the signal mask if requested with + a tail-call for simplicity; it always returns zero. */ + ta ST_FLUSH_WINDOWS + +#ifdef PTR_MANGLE + PTR_MANGLE (%g1, %o7, %g4) + PTR_MANGLE2 (%g2, %sp, %g4) + PTR_MANGLE2 (%g3, %fp, %g4) + st %g1, [%o0 + (JB_PC * 4)] + st %g2, [%o0 + (JB_SP * 4)] + st %g3, [%o0 + (JB_FP * 4)] +#else + st %o7, [%o0 + (JB_PC * 4)] + st %sp, [%o0 + (JB_SP * 4)] + st %fp, [%o0 + (JB_FP * 4)] +#endif + + mov %o7, %g1 + call __sigjmp_save + mov %g1, %o7 +END(__sigsetjmp) +hidden_def (__sigsetjmp) + +weak_extern(_setjmp) +weak_extern(setjmp) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/Makefile b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/Makefile new file mode 100644 index 0000000000..137e26bee9 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/Makefile @@ -0,0 +1,29 @@ +# Software floating-point emulation. +# Makefile for SPARC v8 long double utility functions (_Q_*). +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# This file is part of the GNU C Library. +# Contributed by 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/>. + +ifeq ($(subdir),soft-fp) +sparc32-quad-routines := q_add q_cmp q_cmpe q_div q_dtoq q_feq q_fge \ + q_fgt q_fle q_flt q_fne q_itoq q_mul q_neg q_qtod q_qtoi \ + q_qtos q_qtou q_qtoull q_qtoll q_sqrt q_stoq q_sub q_utoq \ + q_ulltoq q_lltoq q_util +sysdep_routines += $(sparc32-quad-routines) + +endif diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/Versions b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/Versions new file mode 100644 index 0000000000..6a09249c46 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/Versions @@ -0,0 +1,8 @@ +libc { + GLIBC_2.4 { + _Q_add; _Q_cmp; _Q_cmpe; _Q_div; _Q_dtoq; _Q_feq; _Q_fge; _Q_fgt; + _Q_fle; _Q_flt; _Q_fne; _Q_itoq; _Q_mul; _Q_neg; _Q_qtod; _Q_qtoi; + _Q_qtos; _Q_qtou; _Q_qtoull; _Q_qtoll; _Q_sqrt; _Q_stoq; _Q_sub; + _Q_utoq; _Q_ulltoq; _Q_lltoq; + } +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_add.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_add.c new file mode 100644 index 0000000000..2a250dee37 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_add.c @@ -0,0 +1,38 @@ +/* Software floating-point emulation. + Return a + b + 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 "soft-fp.h" +#include "quad.h" + +long double _Q_add(const long double a, const long double b) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); + long double c; + + FP_INIT_ROUNDMODE; + FP_UNPACK_SEMIRAW_Q(A, a); + FP_UNPACK_SEMIRAW_Q(B, b); + FP_ADD_Q(C, A, B); + FP_PACK_SEMIRAW_Q(c, C); + FP_HANDLE_EXCEPTIONS; + return c; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_cmp.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_cmp.c new file mode 100644 index 0000000000..9269cf72ae --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_cmp.c @@ -0,0 +1,38 @@ +/* Software floating-point emulation. + Compare a and b, return float condition code. + 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 "soft-fp.h" +#include "quad.h" + +int _Q_cmp(const long double a, const long double b) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(B); + int r; + + FP_UNPACK_RAW_Q(A, a); + FP_UNPACK_RAW_Q(B, b); + FP_CMP_Q(r, B, A, 3, 1); + if (r == -1) r = 2; + FP_HANDLE_EXCEPTIONS; + + return r; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_cmpe.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_cmpe.c new file mode 100644 index 0000000000..6a46441e8f --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_cmpe.c @@ -0,0 +1,39 @@ +/* Software floating-point emulation. + Compare a and b, return float condition code. + Signal exception (unless masked) if unordered. + 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 "soft-fp.h" +#include "quad.h" + +int _Q_cmpe(const long double a, const long double b) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(B); + int r; + + FP_UNPACK_RAW_Q(A, a); + FP_UNPACK_RAW_Q(B, b); + FP_CMP_Q(r, B, A, 3, 2); + if (r == -1) r = 2; + FP_HANDLE_EXCEPTIONS; + + return r; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_div.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_div.c new file mode 100644 index 0000000000..4920219a4d --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_div.c @@ -0,0 +1,38 @@ +/* Software floating-point emulation. + Return a / b + 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 "soft-fp.h" +#include "quad.h" + +long double _Q_div(const long double a, const long double b) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); + long double c; + + FP_INIT_ROUNDMODE; + FP_UNPACK_Q(A, a); + FP_UNPACK_Q(B, b); + FP_DIV_Q(C, A, B); + FP_PACK_Q(c, C); + FP_HANDLE_EXCEPTIONS; + return c; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_dtoq.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_dtoq.c new file mode 100644 index 0000000000..1d5426dfe9 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_dtoq.c @@ -0,0 +1,43 @@ +/* Software floating-point emulation. + Return (long double)(a) + 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 "soft-fp.h" +#include "double.h" +#include "quad.h" + +long double _Q_dtoq(const double a) +{ + FP_DECL_EX; + FP_DECL_D(A); + FP_DECL_Q(C); + long double c; + + FP_INIT_ROUNDMODE; + FP_UNPACK_RAW_D(A, a); +#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q + FP_EXTEND(Q,D,4,2,C,A); +#else + FP_EXTEND(Q,D,2,1,C,A); +#endif + FP_PACK_RAW_Q(c, C); + FP_HANDLE_EXCEPTIONS; + return c; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_feq.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_feq.c new file mode 100644 index 0000000000..94ba005e61 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_feq.c @@ -0,0 +1,37 @@ +/* Software floating-point emulation. + Return 1 if a == b + 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 "soft-fp.h" +#include "quad.h" + +int _Q_feq(const long double a, const long double b) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(B); + int r; + + FP_UNPACK_RAW_Q(A, a); + FP_UNPACK_RAW_Q(B, b); + FP_CMP_EQ_Q(r, A, B, 1); + FP_HANDLE_EXCEPTIONS; + + return !r; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_fge.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_fge.c new file mode 100644 index 0000000000..09c45d7ef9 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_fge.c @@ -0,0 +1,37 @@ +/* Software floating-point emulation. + Return 1 if a >= b + 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 "soft-fp.h" +#include "quad.h" + +int _Q_fge(const long double a, const long double b) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(B); + int r; + + FP_UNPACK_RAW_Q(A, a); + FP_UNPACK_RAW_Q(B, b); + FP_CMP_Q(r, B, A, 3, 2); + FP_HANDLE_EXCEPTIONS; + + return (r <= 0); +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_fgt.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_fgt.c new file mode 100644 index 0000000000..1386b14434 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_fgt.c @@ -0,0 +1,37 @@ +/* Software floating-point emulation. + Return 1 if a > b + 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 "soft-fp.h" +#include "quad.h" + +int _Q_fgt(const long double a, const long double b) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(B); + int r; + + FP_UNPACK_RAW_Q(A, a); + FP_UNPACK_RAW_Q(B, b); + FP_CMP_Q(r, B, A, 3, 2); + FP_HANDLE_EXCEPTIONS; + + return (r == -1); +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_fle.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_fle.c new file mode 100644 index 0000000000..83b676ee44 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_fle.c @@ -0,0 +1,37 @@ +/* Software floating-point emulation. + Return 1 if a <= b + 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 "soft-fp.h" +#include "quad.h" + +int _Q_fle(const long double a, const long double b) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(B); + int r; + + FP_UNPACK_RAW_Q(A, a); + FP_UNPACK_RAW_Q(B, b); + FP_CMP_Q(r, B, A, -2, 2); + FP_HANDLE_EXCEPTIONS; + + return (r >= 0); +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_flt.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_flt.c new file mode 100644 index 0000000000..f196393b44 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_flt.c @@ -0,0 +1,37 @@ +/* Software floating-point emulation. + Return 1 if a < b + 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 "soft-fp.h" +#include "quad.h" + +int _Q_flt(const long double a, const long double b) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(B); + int r; + + FP_UNPACK_RAW_Q(A, a); + FP_UNPACK_RAW_Q(B, b); + FP_CMP_Q(r, B, A, 3, 2); + FP_HANDLE_EXCEPTIONS; + + return (r == 1); +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_fne.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_fne.c new file mode 100644 index 0000000000..b017d892c9 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_fne.c @@ -0,0 +1,37 @@ +/* Software floating-point emulation. + Return 1 if a != b + 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 "soft-fp.h" +#include "quad.h" + +int _Q_fne(const long double a, const long double b) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(B); + int r; + + FP_UNPACK_RAW_Q(A, a); + FP_UNPACK_RAW_Q(B, b); + FP_CMP_EQ_Q(r, A, B, 1); + FP_HANDLE_EXCEPTIONS; + + return r; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_itoq.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_itoq.c new file mode 100644 index 0000000000..e11938cc43 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_itoq.c @@ -0,0 +1,35 @@ +/* Software floating-point emulation. + Return (long double)(a) + 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/>. */ + +#define FP_NO_EXCEPTIONS +#include "soft-fp.h" +#include "quad.h" + +long double _Q_itoq(const int a) +{ + FP_DECL_Q(C); + int b = a; + long double c; + + FP_FROM_INT_Q(C, b, 32, unsigned int); + FP_PACK_RAW_Q(c, C); + return c; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_lltoq.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_lltoq.c new file mode 100644 index 0000000000..b94443dd65 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_lltoq.c @@ -0,0 +1,35 @@ +/* Software floating-point emulation. + Return (long double)a + 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/>. */ + +#define FP_NO_EXCEPTIONS +#include "soft-fp.h" +#include "quad.h" + +long double _Q_lltoq(const long long a) +{ + FP_DECL_Q(C); + long double c; + long long b = a; + + FP_FROM_INT_Q(C, b, 64, unsigned long long); + FP_PACK_RAW_Q(c, C); + return c; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_mul.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_mul.c new file mode 100644 index 0000000000..8892f0ef93 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_mul.c @@ -0,0 +1,38 @@ +/* Software floating-point emulation. + Return a * b + 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 "soft-fp.h" +#include "quad.h" + +long double _Q_mul(const long double a, const long double b) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); + long double c; + + FP_INIT_ROUNDMODE; + FP_UNPACK_Q(A, a); + FP_UNPACK_Q(B, b); + FP_MUL_Q(C, A, B); + FP_PACK_Q(c, C); + FP_HANDLE_EXCEPTIONS; + return c; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_neg.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_neg.c new file mode 100644 index 0000000000..9660d17eac --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_neg.c @@ -0,0 +1,48 @@ +/* Software floating-point emulation. + Return !a + 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 "soft-fp.h" +#include "quad.h" + +long double _Q_neg(const long double a) +{ + union { + long double ldbl; + UWtype words[4]; + } c; + + c.ldbl = a; + +#if (__BYTE_ORDER == __BIG_ENDIAN) + c.words[0] ^= (((UWtype)1) << (W_TYPE_SIZE - 1)); +#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 64) + c.words[1] ^= (((UWtype)1) << (W_TYPE_SIZE - 1)); +#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 32) + c.words[3] ^= (((UWtype)1) << (W_TYPE_SIZE - 1)); +#else + FP_DECL_Q(A); FP_DECL_Q(C); + + FP_UNPACK_RAW_Q(A, a); + FP_NEG_Q(C, A); + FP_PACK_RAW_Q(c.ldbl, C); +#endif + return c.ldbl; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtod.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtod.c new file mode 100644 index 0000000000..9d7b80ef3e --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtod.c @@ -0,0 +1,44 @@ +/* Software floating-point emulation. + Return (double)a + 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 "soft-fp.h" +#include "double.h" +#include "quad.h" + +double _Q_qtod(const long double a) +{ + FP_DECL_EX; + FP_DECL_Q(A); + FP_DECL_D(R); + double r; + + FP_INIT_ROUNDMODE; + FP_UNPACK_SEMIRAW_Q(A, a); +#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q + FP_TRUNC(D,Q,2,4,R,A); +#else + FP_TRUNC(D,Q,1,2,R,A); +#endif + FP_PACK_SEMIRAW_D(r, R); + FP_HANDLE_EXCEPTIONS; + + return r; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtoi.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtoi.c new file mode 100644 index 0000000000..5d362b70e4 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtoi.c @@ -0,0 +1,37 @@ +/* Software floating-point emulation. + Return (int)a + 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/>. */ + +#define FP_ROUNDMODE FP_RND_ZERO +#include "soft-fp.h" +#include "quad.h" + +int _Q_qtoi(const long double a) +{ + FP_DECL_EX; + FP_DECL_Q(A); + unsigned int r; + + FP_UNPACK_RAW_Q(A, a); + FP_TO_INT_Q(r, A, 32, 1); + FP_HANDLE_EXCEPTIONS; + + return r; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtoll.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtoll.c new file mode 100644 index 0000000000..bfaa64ac11 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtoll.c @@ -0,0 +1,37 @@ +/* Software floating-point emulation. + Return (long long)a + 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/>. */ + +#define FP_ROUNDMODE FP_RND_ZERO +#include "soft-fp.h" +#include "quad.h" + +long long _Q_qtoll(const long double a) +{ + FP_DECL_EX; + FP_DECL_Q(A); + unsigned long long r; + + FP_UNPACK_RAW_Q(A, a); + FP_TO_INT_Q(r, A, 64, 1); + FP_HANDLE_EXCEPTIONS; + + return r; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtos.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtos.c new file mode 100644 index 0000000000..b2642def3b --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtos.c @@ -0,0 +1,44 @@ +/* Software floating-point emulation. + Return (float)a + 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 "soft-fp.h" +#include "single.h" +#include "quad.h" + +float _Q_qtos(const long double a) +{ + FP_DECL_EX; + FP_DECL_Q(A); + FP_DECL_S(R); + float r; + + FP_INIT_ROUNDMODE; + FP_UNPACK_SEMIRAW_Q(A, a); +#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q + FP_TRUNC(S,Q,1,4,R,A); +#else + FP_TRUNC(S,Q,1,2,R,A); +#endif + FP_PACK_SEMIRAW_S(r, R); + FP_HANDLE_EXCEPTIONS; + + return r; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtou.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtou.c new file mode 100644 index 0000000000..3940a2f5b6 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtou.c @@ -0,0 +1,37 @@ +/* Software floating-point emulation. + Return (unsigned int)a + 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/>. */ + +#define FP_ROUNDMODE FP_RND_ZERO +#include "soft-fp.h" +#include "quad.h" + +unsigned int _Q_qtou(const long double a) +{ + FP_DECL_EX; + FP_DECL_Q(A); + unsigned int r; + + FP_UNPACK_RAW_Q(A, a); + FP_TO_INT_Q(r, A, 32, -1); + FP_HANDLE_EXCEPTIONS; + + return r; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtoull.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtoull.c new file mode 100644 index 0000000000..83fabef05c --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_qtoull.c @@ -0,0 +1,37 @@ +/* Software floating-point emulation. + Return (unsigned long long)a + 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/>. */ + +#define FP_ROUNDMODE FP_RND_ZERO +#include "soft-fp.h" +#include "quad.h" + +unsigned long long _Q_qtoull(const long double a) +{ + FP_DECL_EX; + FP_DECL_Q(A); + unsigned long long r; + + FP_UNPACK_RAW_Q(A, a); + FP_TO_INT_Q(r, A, 64, -1); + FP_HANDLE_EXCEPTIONS; + + return r; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_sqrt.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_sqrt.c new file mode 100644 index 0000000000..c3939446fe --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_sqrt.c @@ -0,0 +1,37 @@ +/* Software floating-point emulation. + Return sqrtl(a) + 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 "soft-fp.h" +#include "quad.h" + +long double _Q_sqrt(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; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_stoq.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_stoq.c new file mode 100644 index 0000000000..b011d801b4 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_stoq.c @@ -0,0 +1,42 @@ +/* Software floating-point emulation. + c = (long double)(a) + 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 "soft-fp.h" +#include "single.h" +#include "quad.h" + +long double _Q_stoq(const float a) +{ + FP_DECL_EX; + FP_DECL_S(A); + FP_DECL_Q(C); + long double c; + + FP_UNPACK_RAW_S(A, a); +#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q + FP_EXTEND(Q,S,4,1,C,A); +#else + FP_EXTEND(Q,S,2,1,C,A); +#endif + FP_PACK_RAW_Q(c, C); + FP_HANDLE_EXCEPTIONS; + return c; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_sub.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_sub.c new file mode 100644 index 0000000000..69d78cd85a --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_sub.c @@ -0,0 +1,38 @@ +/* Software floating-point emulation. + c = a - b + 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 "soft-fp.h" +#include "quad.h" + +long double _Q_sub(const long double a, const long double b) +{ + FP_DECL_EX; + FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); + long double c; + + FP_INIT_ROUNDMODE; + FP_UNPACK_SEMIRAW_Q(A, a); + FP_UNPACK_SEMIRAW_Q(B, b); + FP_SUB_Q(C, A, B); + FP_PACK_SEMIRAW_Q(c, C); + FP_HANDLE_EXCEPTIONS; + return c; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_ulltoq.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_ulltoq.c new file mode 100644 index 0000000000..97586cb588 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_ulltoq.c @@ -0,0 +1,35 @@ +/* Software floating-point emulation. + Return (long double)(a) + 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/>. */ + +#define FP_NO_EXCEPTIONS +#include "soft-fp.h" +#include "quad.h" + +long double _Q_ulltoq(const unsigned long long a) +{ + FP_DECL_Q(C); + long double c; + unsigned long long b = a; + + FP_FROM_INT_Q(C, b, 64, unsigned long long); + FP_PACK_RAW_Q(c, C); + return c; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_util.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_util.c new file mode 100644 index 0000000000..35de7ee791 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_util.c @@ -0,0 +1,62 @@ +/* Software floating-point emulation. + Helper routine for _Q_* routines. + Simulate exceptions using double arithmetics. + Copyright (C) 1999-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by 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 <float.h> +#include <math.h> +#include <assert.h> +#include "soft-fp.h" + +unsigned long long ___Q_zero = 0x0000000000000000ULL; + +void ___Q_simulate_exceptions(int exceptions) +{ + if (exceptions & FP_EX_INVALID) + { + float f = 0.0; + __asm__ __volatile__ ("fdivs %0, %0, %0" : "+f" (f)); + } + if (exceptions & FP_EX_DIVZERO) + { + float f = 1.0, g = 0.0; + __asm__ __volatile__ ("fdivs %0, %1, %0" + : "+f" (f) + : "f" (g)); + } + if (exceptions & FP_EX_OVERFLOW) + { + float f = FLT_MAX; + __asm__ __volatile__("fmuls %0, %0, %0" : "+f" (f)); + exceptions &= ~FP_EX_INEXACT; + } + if (exceptions & FP_EX_UNDERFLOW) + { + float f = FLT_MIN; + __asm__ __volatile__("fmuls %0, %0, %0" : "+f" (f)); + exceptions &= ~FP_EX_INEXACT; + } + if (exceptions & FP_EX_INEXACT) + { + double d = 1.0, e = M_PI; + __asm__ __volatile__ ("fdivd %0, %1, %0" + : "+f" (d) + : "f" (e)); + } +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_utoq.c b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_utoq.c new file mode 100644 index 0000000000..48337ccb0e --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/q_utoq.c @@ -0,0 +1,35 @@ +/* Software floating-point emulation. + c = (long double)(a) + 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/>. */ + +#define FP_NO_EXCEPTIONS +#include "soft-fp.h" +#include "quad.h" + +long double _Q_utoq(const unsigned int a) +{ + FP_DECL_Q(C); + long double c; + unsigned int b = a; + + FP_FROM_INT_Q(C, b, 32, unsigned int); + FP_PACK_RAW_Q(c, C); + return c; +} diff --git a/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h new file mode 100644 index 0000000000..de9d56ec46 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h @@ -0,0 +1,218 @@ +/* Machine-dependent software floating-point definitions. + Sparc userland (_Q_*) version. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson (rth@cygnus.com), + Jakub Jelinek (jj@ultra.linux.cz) and + David S. Miller (davem@redhat.com). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <fpu_control.h> +#include <stdlib.h> + +#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_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(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) + +#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 +#define _FP_NANSIGN_S 0 +#define _FP_NANSIGN_D 0 +#define _FP_NANSIGN_Q 0 + +#define _FP_KEEPNANFRACP 1 +#define _FP_QNANNEGATEDP 0 + +/* If one NaN is signaling and the other is not, + * we choose that one, otherwise we choose X. + */ +/* For _Qp_* and _Q_*, this should prefer X, for + * CPU instruction emulation this should prefer Y. + * (see SPAMv9 B.2.2 section). + */ +#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ + do { \ + if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \ + && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \ + { \ + R##_s = Y##_s; \ + _FP_FRAC_COPY_##wc(R,Y); \ + } \ + else \ + { \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc(R,X); \ + } \ + R##_c = FP_CLS_NAN; \ + } while (0) + +/* Some assembly to speed things up. */ +#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ + __asm__ ("addcc %r7,%8,%2\n\ + addxcc %r5,%6,%1\n\ + addx %r3,%4,%0" \ + : "=r" ((USItype)(r2)), \ + "=&r" ((USItype)(r1)), \ + "=&r" ((USItype)(r0)) \ + : "%rJ" ((USItype)(x2)), \ + "rI" ((USItype)(y2)), \ + "%rJ" ((USItype)(x1)), \ + "rI" ((USItype)(y1)), \ + "%rJ" ((USItype)(x0)), \ + "rI" ((USItype)(y0)) \ + : "cc") + +#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ + __asm__ ("subcc %r7,%8,%2\n\ + subxcc %r5,%6,%1\n\ + subx %r3,%4,%0" \ + : "=r" ((USItype)(r2)), \ + "=&r" ((USItype)(r1)), \ + "=&r" ((USItype)(r0)) \ + : "%rJ" ((USItype)(x2)), \ + "rI" ((USItype)(y2)), \ + "%rJ" ((USItype)(x1)), \ + "rI" ((USItype)(y1)), \ + "%rJ" ((USItype)(x0)), \ + "rI" ((USItype)(y0)) \ + : "cc") + +#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ + do { \ + /* We need to fool gcc, as we need to pass more than 10 \ + input/outputs. */ \ + register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \ + __asm__ __volatile__ ("\ + addcc %r8,%9,%1\n\ + addxcc %r6,%7,%0\n\ + addxcc %r4,%5,%%g2\n\ + addx %r2,%3,%%g1" \ + : "=&r" ((USItype)(r1)), \ + "=&r" ((USItype)(r0)) \ + : "%rJ" ((USItype)(x3)), \ + "rI" ((USItype)(y3)), \ + "%rJ" ((USItype)(x2)), \ + "rI" ((USItype)(y2)), \ + "%rJ" ((USItype)(x1)), \ + "rI" ((USItype)(y1)), \ + "%rJ" ((USItype)(x0)), \ + "rI" ((USItype)(y0)) \ + : "cc", "g1", "g2"); \ + __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2)); \ + r3 = _t1; r2 = _t2; \ + } while (0) + +#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ + do { \ + /* We need to fool gcc, as we need to pass more than 10 \ + input/outputs. */ \ + register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \ + __asm__ __volatile__ ("\ + subcc %r8,%9,%1\n\ + subxcc %r6,%7,%0\n\ + subxcc %r4,%5,%%g2\n\ + subx %r2,%3,%%g1" \ + : "=&r" ((USItype)(r1)), \ + "=&r" ((USItype)(r0)) \ + : "%rJ" ((USItype)(x3)), \ + "rI" ((USItype)(y3)), \ + "%rJ" ((USItype)(x2)), \ + "rI" ((USItype)(y2)), \ + "%rJ" ((USItype)(x1)), \ + "rI" ((USItype)(y1)), \ + "%rJ" ((USItype)(x0)), \ + "rI" ((USItype)(y0)) \ + : "cc", "g1", "g2"); \ + __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2)); \ + r3 = _t1; r2 = _t2; \ + } while (0) + +#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0) + +#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0) + +#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \ + __asm__ ("addcc %3,%4,%3\n\ + addxcc %2,%%g0,%2\n\ + addxcc %1,%%g0,%1\n\ + addx %0,%%g0,%0" \ + : "=&r" ((USItype)(x3)), \ + "=&r" ((USItype)(x2)), \ + "=&r" ((USItype)(x1)), \ + "=&r" ((USItype)(x0)) \ + : "rI" ((USItype)(i)), \ + "0" ((USItype)(x3)), \ + "1" ((USItype)(x2)), \ + "2" ((USItype)(x1)), \ + "3" ((USItype)(x0)) \ + : "cc") + +/* Obtain the current rounding mode. */ +#ifndef FP_ROUNDMODE +#define FP_ROUNDMODE ((_fcw >> 30) & 0x3) +#endif + +/* Exception flags. */ +#define FP_EX_INVALID (1 << 4) +#define FP_EX_OVERFLOW (1 << 3) +#define FP_EX_UNDERFLOW (1 << 2) +#define FP_EX_DIVZERO (1 << 1) +#define FP_EX_INEXACT (1 << 0) + +#define _FP_TININESS_AFTER_ROUNDING 0 + +#define _FP_DECL_EX \ + fpu_control_t _fcw __attribute__ ((unused)) = (FP_RND_NEAREST << 30) + +#define FP_INIT_ROUNDMODE \ +do { \ + _FPU_GETCW(_fcw); \ +} while (0) + +#define FP_TRAPPING_EXCEPTIONS ((_fcw >> 23) & 0x1f) +#define FP_INHIBIT_RESULTS ((_fcw >> 23) & _fex) + +/* Simulate exceptions using double arithmetics. */ +extern void ___Q_simulate_exceptions(int exc); + +#define FP_HANDLE_EXCEPTIONS \ +do { \ + if (!_fex) \ + { \ + /* This is the common case, so we do it inline. \ + * We need to clear cexc bits if any. \ + */ \ + extern unsigned long long ___Q_zero; \ + __asm__ __volatile__("ldd [%0], %%f30\n\t" \ + "faddd %%f30, %%f30, %%f30" \ + : : "r" (&___Q_zero) : "f30"); \ + } \ + else \ + ___Q_simulate_exceptions (_fex); \ +} while (0) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/Makefile b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/Makefile new file mode 100644 index 0000000000..2ff9853458 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/Makefile @@ -0,0 +1 @@ +sysdep-CFLAGS += -mcpu=v8 diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/addmul_1.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/addmul_1.S new file mode 100644 index 0000000000..20e37c2d0b --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/addmul_1.S @@ -0,0 +1,118 @@ +! SPARC v8 __mpn_addmul_1 -- Multiply a limb vector with a limb and +! add the result 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; see the file COPYING.LIB. If not, +! see <http://www.gnu.org/licenses/>. + + +! INPUT PARAMETERS +! res_ptr o0 +! s1_ptr o1 +! size o2 +! s2_limb o3 + +#include <sysdep.h> + +ENTRY(__mpn_addmul_1) + ld [%o1+0],%o4 ! 1 + sll %o2,4,%g1 + orcc %g0,%g0,%g2 + mov %o7,%g4 ! Save return address register + and %g1,(4-1)<<4,%g1 +1: call 2f + add %o7,3f-1b,%g3 +2: jmp %g3+%g1 + mov %g4,%o7 ! Restore return address register + + .align 4 +3: +LOC(00): + add %o0,-4,%o0 + b LOC(loop00) /* 4, 8, 12, ... */ + add %o1,-4,%o1 + nop +LOC(01): + b LOC(loop01) /* 1, 5, 9, ... */ + nop + nop + nop +LOC(10): + add %o0,-12,%o0 /* 2, 6, 10, ... */ + b LOC(loop10) + add %o1,4,%o1 + nop +LOC(11): + add %o0,-8,%o0 /* 3, 7, 11, ... */ + b LOC(loop11) + add %o1,-8,%o1 + nop + +LOC(loop): + addcc %g3,%g2,%g3 ! 1 + ld [%o1+4],%o4 ! 2 + rd %y,%g2 ! 1 + addx %g0,%g2,%g2 + ld [%o0+0],%g1 ! 2 + addcc %g1,%g3,%g3 + st %g3,[%o0+0] ! 1 +LOC(loop00): + umul %o4,%o3,%g3 ! 2 + ld [%o0+4],%g1 ! 2 + addxcc %g3,%g2,%g3 ! 2 + ld [%o1+8],%o4 ! 3 + rd %y,%g2 ! 2 + addx %g0,%g2,%g2 + nop + addcc %g1,%g3,%g3 + st %g3,[%o0+4] ! 2 +LOC(loop11): + umul %o4,%o3,%g3 ! 3 + addxcc %g3,%g2,%g3 ! 3 + ld [%o1+12],%o4 ! 4 + rd %y,%g2 ! 3 + add %o1,16,%o1 + addx %g0,%g2,%g2 + ld [%o0+8],%g1 ! 2 + addcc %g1,%g3,%g3 + st %g3,[%o0+8] ! 3 +LOC(loop10): + umul %o4,%o3,%g3 ! 4 + addxcc %g3,%g2,%g3 ! 4 + ld [%o1+0],%o4 ! 1 + rd %y,%g2 ! 4 + addx %g0,%g2,%g2 + ld [%o0+12],%g1 ! 2 + addcc %g1,%g3,%g3 + st %g3,[%o0+12] ! 4 + add %o0,16,%o0 + addx %g0,%g2,%g2 +LOC(loop01): + addcc %o2,-4,%o2 + bg LOC(loop) + umul %o4,%o3,%g3 ! 1 + + addcc %g3,%g2,%g3 ! 4 + rd %y,%g2 ! 4 + addx %g0,%g2,%g2 + ld [%o0+0],%g1 ! 2 + addcc %g1,%g3,%g3 + st %g3,[%o0+0] ! 4 + retl + addx %g0,%g2,%o0 + +END(__mpn_addmul_1) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/dotmul.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/dotmul.S new file mode 100644 index 0000000000..9b20cc3684 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/dotmul.S @@ -0,0 +1,13 @@ +/* + * Sparc v8 has multiply. + */ + +#include <sysdep.h> + +ENTRY(.mul) + + smul %o0, %o1, %o0 + retl + rd %y, %o1 + +END(.mul) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/mul_1.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/mul_1.S new file mode 100644 index 0000000000..49a2213c0f --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/mul_1.S @@ -0,0 +1,102 @@ +! SPARC v8 __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; see the file COPYING.LIB. If not, +! see <http://www.gnu.org/licenses/>. + + +! INPUT PARAMETERS +! res_ptr o0 +! s1_ptr o1 +! size o2 +! s2_limb o3 + +#include <sysdep.h> + +ENTRY(__mpn_mul_1) + sll %o2,4,%g1 + mov %o7,%g4 ! Save return address register + and %g1,(4-1)<<4,%g1 +1: call 2f + add %o7,3f-1b,%g3 +2: mov %g4,%o7 ! Restore return address register + jmp %g3+%g1 + ld [%o1+0],%o4 ! 1 + + .align 4 +3: +LOC(00): + add %o0,-4,%o0 + add %o1,-4,%o1 + b LOC(loop00) /* 4, 8, 12, ... */ + orcc %g0,%g0,%g2 +LOC(01): + b LOC(loop01) /* 1, 5, 9, ... */ + orcc %g0,%g0,%g2 + nop + nop +LOC(10): + add %o0,-12,%o0 /* 2, 6, 10, ... */ + add %o1,4,%o1 + b LOC(loop10) + orcc %g0,%g0,%g2 + nop +LOC(11): + add %o0,-8,%o0 /* 3, 7, 11, ... */ + add %o1,-8,%o1 + b LOC(loop11) + orcc %g0,%g0,%g2 + +LOC(loop): + addcc %g3,%g2,%g3 ! 1 + ld [%o1+4],%o4 ! 2 + st %g3,[%o0+0] ! 1 + rd %y,%g2 ! 1 +LOC(loop00): + umul %o4,%o3,%g3 ! 2 + addxcc %g3,%g2,%g3 ! 2 + ld [%o1+8],%o4 ! 3 + st %g3,[%o0+4] ! 2 + rd %y,%g2 ! 2 +LOC(loop11): + umul %o4,%o3,%g3 ! 3 + addxcc %g3,%g2,%g3 ! 3 + ld [%o1+12],%o4 ! 4 + add %o1,16,%o1 + st %g3,[%o0+8] ! 3 + rd %y,%g2 ! 3 +LOC(loop10): + umul %o4,%o3,%g3 ! 4 + addxcc %g3,%g2,%g3 ! 4 + ld [%o1+0],%o4 ! 1 + st %g3,[%o0+12] ! 4 + add %o0,16,%o0 + rd %y,%g2 ! 4 + addx %g0,%g2,%g2 +LOC(loop01): + addcc %o2,-4,%o2 + bg LOC(loop) + umul %o4,%o3,%g3 ! 1 + + addcc %g3,%g2,%g3 ! 4 + st %g3,[%o0+0] ! 4 + rd %y,%g2 ! 4 + retl + addx %g0,%g2,%o0 + +END(__mpn_mul_1) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/rem.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/rem.S new file mode 100644 index 0000000000..a2694e699e --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/rem.S @@ -0,0 +1,21 @@ +/* + * Sparc v8 has divide. + */ + +#include <sysdep.h> + +ENTRY(.rem) + + sra %o0, 31, %o2 + wr %o2, 0, %y + nop + nop + nop + sdivcc %o0, %o1, %o2 + bvs,a 1f + xnor %o2, %g0, %o2 +1: smul %o2, %o1, %o2 + retl + sub %o0, %o2, %o0 + +END(.rem) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/sdiv.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/sdiv.S new file mode 100644 index 0000000000..bfc4acf2fa --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/sdiv.S @@ -0,0 +1,20 @@ +/* + * Sparc v8 has divide. + */ + +#include <sysdep.h> + +ENTRY(.div) + + sra %o0, 31, %o2 + wr %o2, 0, %y + nop + nop + nop + sdivcc %o0, %o1, %o0 + bvs,a 1f + xnor %o0, %g0, %o0 +1: retl + nop + +END(.div) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/submul_1.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/submul_1.S new file mode 100644 index 0000000000..b9cb561ef4 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/submul_1.S @@ -0,0 +1,57 @@ +! SPARC v8 __mpn_submul_1 -- Multiply a limb vector with a limb and +! subtract the result 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; see the file COPYING.LIB. If not, +! see <http://www.gnu.org/licenses/>. + + +! INPUT PARAMETERS +! res_ptr o0 +! s1_ptr o1 +! size o2 +! s2_limb o3 + +#include <sysdep.h> + +ENTRY(__mpn_submul_1) + sub %g0,%o2,%o2 ! negate ... + sll %o2,2,%o2 ! ... and scale size + sub %o1,%o2,%o1 ! o1 is offset s1_ptr + sub %o0,%o2,%g1 ! g1 is offset res_ptr + + mov 0,%o0 ! clear cy_limb + +LOC(loop): + ld [%o1+%o2],%o4 + ld [%g1+%o2],%g2 + umul %o4,%o3,%o5 + rd %y,%g3 + addcc %o5,%o0,%o5 + addx %g3,0,%o0 + subcc %g2,%o5,%g2 + addx %o0,0,%o0 + st %g2,[%g1+%o2] + + addcc %o2,4,%o2 + bne LOC(loop) + nop + + retl + nop + +END(__mpn_submul_1) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/udiv.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/udiv.S new file mode 100644 index 0000000000..e9cab4e4ef --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/udiv.S @@ -0,0 +1,16 @@ +/* + * Sparc v8 has divide. + */ + +#include <sysdep.h> + +ENTRY(.udiv) + + wr %g0, 0, %y + nop + nop + retl + udiv %o0, %o1, %o0 + +END(.udiv) +strong_alias (.udiv, __wrap_.udiv) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/umul.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/umul.S new file mode 100644 index 0000000000..cec454a7dd --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/umul.S @@ -0,0 +1,13 @@ +/* + * Sparc v8 has multiply. + */ + +#include <sysdep.h> + +ENTRY(.umul) + + umul %o0, %o1, %o0 + retl + rd %y, %o1 + +END(.umul) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/urem.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/urem.S new file mode 100644 index 0000000000..cc2689d514 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv8/urem.S @@ -0,0 +1,18 @@ +/* + * Sparc v8 has divide. + */ + +#include <sysdep.h> + +ENTRY(.urem) + + wr %g0, 0, %y + nop + nop + nop + udiv %o0, %o1, %o2 + umul %o2, %o1, %o2 + retl + sub %o0, %o2, %o0 + +END(.urem) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/Makefile b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/Makefile new file mode 100644 index 0000000000..526673e7b4 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/Makefile @@ -0,0 +1,22 @@ +sysdep-CFLAGS += -mcpu=ultrasparc -Wa,-Av9a -mvis + +ifeq ($(have-as-vis3),yes) +ASFLAGS-.o += -Wa,-Av9d +ASFLAGS-.os += -Wa,-Av9d +ASFLAGS-.op += -Wa,-Av9d +ASFLAGS-.oS += -Wa,-Av9d +else +ASFLAGS-.o += -Wa,-Av9a +ASFLAGS-.os += -Wa,-Av9a +ASFLAGS-.op += -Wa,-Av9a +ASFLAGS-.oS += -Wa,-Av9a +endif + +# nscd uses atomic_spin_nop which in turn requires cpu_relax +ifeq ($(subdir),nscd) +routines += cpu_relax +endif + +ifeq ($(subdir), nptl) +libpthread-routines += cpu_relax +endif diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/addmul_1.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/addmul_1.S new file mode 100644 index 0000000000..7d3114a846 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/addmul_1.S @@ -0,0 +1,81 @@ +! SPARC v9 32-bit __mpn_addmul_1 -- Multiply a limb vector with a limb +! and add the result to a second limb vector. +! +! Copyright (C) 2013-2017 Free Software Foundation, Inc. +! This file is part of the GNU C Library. +! Contributed by David S. Miller <davem@davemloft.net> +! +! The GNU C Library is free software; you can redistribute it and/or +! modify it under the terms of the GNU Lesser General Public +! License as published by the Free Software Foundation; either +! version 2.1 of the License, or (at your option) any later version. +! +! The GNU C Library is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +! Lesser General Public License for 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> + +#define res_ptr %i0 +#define s1_ptr %i1 +#define sz_arg %i2 +#define s2l_arg %i3 +#define sz %o4 +#define carry %o5 +#define s2_limb %g1 +#define tmp1 %l0 +#define tmp2 %l1 +#define tmp3 %l2 +#define tmp4 %l3 +#define tmp64_1 %g3 +#define tmp64_2 %o3 + +ENTRY(__mpn_addmul_1) + save %sp, -96, %sp + srl sz_arg, 0, sz + srl s2l_arg, 0, s2_limb + subcc sz, 1, sz + be,pn %icc, .Lfinal_limb + clr carry + +.Lloop: + lduw [s1_ptr + 0x00], tmp1 + lduw [res_ptr + 0x00], tmp3 + lduw [s1_ptr + 0x04], tmp2 + lduw [res_ptr + 0x04], tmp4 + mulx tmp1, s2_limb, tmp64_1 + add s1_ptr, 8, s1_ptr + mulx tmp2, s2_limb, tmp64_2 + sub sz, 2, sz + add res_ptr, 8, res_ptr + add tmp3, tmp64_1, tmp64_1 + add carry, tmp64_1, tmp64_1 + stw tmp64_1, [res_ptr - 0x08] + srlx tmp64_1, 32, carry + add tmp4, tmp64_2, tmp64_2 + add carry, tmp64_2, tmp64_2 + stw tmp64_2, [res_ptr - 0x04] + brgz sz, .Lloop + srlx tmp64_2, 32, carry + + brlz,pt sz, .Lfinish + nop + +.Lfinal_limb: + lduw [s1_ptr + 0x00], tmp1 + lduw [res_ptr + 0x00], tmp3 + mulx tmp1, s2_limb, tmp64_1 + add tmp3, tmp64_1, tmp64_1 + add carry, tmp64_1, tmp64_1 + stw tmp64_1, [res_ptr + 0x00] + srlx tmp64_1, 32, carry + +.Lfinish: + jmpl %i7 + 0x8, %g0 + restore carry, 0, %o0 +END(__mpn_addmul_1) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/atomic-machine.h b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/atomic-machine.h new file mode 100644 index 0000000000..2b36dfc94d --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/atomic-machine.h @@ -0,0 +1,108 @@ +/* Atomic operations. sparcv9 version. + Copyright (C) 2003-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdint.h> + +typedef int8_t atomic8_t; +typedef uint8_t uatomic8_t; +typedef int_fast8_t atomic_fast8_t; +typedef uint_fast8_t uatomic_fast8_t; + +typedef int16_t atomic16_t; +typedef uint16_t uatomic16_t; +typedef int_fast16_t atomic_fast16_t; +typedef uint_fast16_t uatomic_fast16_t; + +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; + +#define __HAVE_64B_ATOMICS 0 +#define USE_ATOMIC_COMPILER_BUILTINS 0 + +/* XXX Is this actually correct? */ +#define ATOMIC_EXCHANGE_USES_CAS 0 + + +#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ + (abort (), (__typeof (*mem)) 0) + +#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ + (abort (), (__typeof (*mem)) 0) + +#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ +({ \ + __typeof (*(mem)) __acev_tmp; \ + __typeof (mem) __acev_mem = (mem); \ + if (__builtin_constant_p (oldval) && (oldval) == 0) \ + __asm __volatile ("cas [%3], %%g0, %0" \ + : "=r" (__acev_tmp), "=m" (*__acev_mem) \ + : "m" (*__acev_mem), "r" (__acev_mem), \ + "0" (newval) : "memory"); \ + else \ + __asm __volatile ("cas [%4], %2, %0" \ + : "=r" (__acev_tmp), "=m" (*__acev_mem) \ + : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \ + "0" (newval) : "memory"); \ + __acev_tmp; }) + +/* This can be implemented if needed. */ +#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ + (abort (), (__typeof (*mem)) 0) + +#define atomic_exchange_acq(mem, newvalue) \ + ({ __typeof (*(mem)) __oldval; \ + __typeof (mem) __memp = (mem); \ + __typeof (*(mem)) __value = (newvalue); \ + \ + if (sizeof (*(mem)) == 4) \ + __asm ("swap %0, %1" \ + : "=m" (*__memp), "=r" (__oldval) \ + : "m" (*__memp), "1" (__value) : "memory"); \ + else \ + abort (); \ + __oldval; }) + +#define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \ + atomic_compare_and_exchange_val_acq (mem, newval, oldval) + +#define atomic_exchange_24_rel(mem, newval) \ + atomic_exchange_rel (mem, newval) + +#define atomic_full_barrier() \ + __asm __volatile ("membar #LoadLoad | #LoadStore" \ + " | #StoreLoad | #StoreStore" : : : "memory") +#define atomic_read_barrier() \ + __asm __volatile ("membar #LoadLoad | #LoadStore" : : : "memory") +#define atomic_write_barrier() \ + __asm __volatile ("membar #LoadStore | #StoreStore" : : : "memory") + +extern void __cpu_relax (void); +#define atomic_spin_nop() __cpu_relax () diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/backtrace.h b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/backtrace.h new file mode 100644 index 0000000000..8d6c756717 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/backtrace.h @@ -0,0 +1,7 @@ +/* Private macros for guiding the backtrace implementation, sparc32 v9 + version. */ + +#define backtrace_flush_register_windows() \ + asm volatile ("flushw") + +#define BACKTRACE_STACK_BIAS 0 diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/bzero.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/bzero.c new file mode 100644 index 0000000000..37f0f6f993 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/bzero.c @@ -0,0 +1 @@ +/* bzero is in memset.S */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/cpu_relax.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/cpu_relax.S new file mode 100644 index 0000000000..41a5e72b25 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/cpu_relax.S @@ -0,0 +1 @@ +#include <sysdeps/sparc/sparc64/cpu_relax.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/dotmul.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/dotmul.S new file mode 100644 index 0000000000..811cf1e89e --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/dotmul.S @@ -0,0 +1,17 @@ +/* + * Sparc v9 has multiply. + */ + +#include <sysdep.h> + + .text + .align 32 +ENTRY(.mul) + + sra %o0, 0, %o0 + sra %o1, 0, %o1 + mulx %o0, %o1, %o0 + retl + srax %o0, 32, %o1 + +END(.mul) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/Makefile b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/Makefile new file mode 100644 index 0000000000..322e300097 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/Makefile @@ -0,0 +1,14 @@ +ifeq ($(subdir),math) +ifeq ($(have-as-vis3),yes) +libm-sysdep_routines += m_copysignf-vis3 m_copysign-vis3 s_fabs-vis3 \ + s_fabsf-vis3 s_llrintf-vis3 s_llrint-vis3 \ + s_rintf-vis3 s_rint-vis3 \ + w_sqrt_compat-vis3 w_sqrtf_compat-vis3 \ + s_fmaf-vis3 s_fma-vis3 s_nearbyint-vis3 \ + s_nearbyintf-vis3 s_fdimf-vis3 s_fdim-vis3 +sysdep_routines += s_copysignf-vis3 s_copysign-vis3 + +CFLAGS-s_fdimf-vis3.c += -Wa,-Av9d -mvis3 +CFLAGS-s_fdim-vis3.c += -Wa,-Av9d -mvis3 +endif +endif diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_copysign-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_copysign-vis3.S new file mode 100644 index 0000000000..aa8b6169a1 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_copysign-vis3.S @@ -0,0 +1,30 @@ +/* copysign function, sparc32 vis3 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + +ENTRY (__copysign_vis3) + sethi %hi(0x80000000), %g1 + and %o2, %g1, %o4 + andn %o0, %g1, %o0 + or %o0, %o4, %o0 + movwtos %o0, %f0 + retl + movwtos %o1, %f1 +END (__copysign_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_copysign.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_copysign.S new file mode 100644 index 0000000000..cdd98c00f4 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_copysign.S @@ -0,0 +1,12 @@ +#include <sparc-ifunc.h> + +SPARC_ASM_VIS3_IFUNC(copysign) + +weak_alias (__copysign, copysign) + +# undef weak_alias +# define weak_alias(a, b) + +#define __copysign __copysign_generic + +#include "../../../fpu/s_copysign.S" diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_copysignf-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_copysignf-vis3.S new file mode 100644 index 0000000000..0f702b32aa --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_copysignf-vis3.S @@ -0,0 +1,29 @@ +/* float copysign function, sparc32 vis3 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + +ENTRY (__copysignf_vis3) + sethi %hi(0x80000000), %g1 + and %o1, %g1, %o4 + andn %o0, %g1, %o0 + or %o0, %o4, %o0 + retl + movwtos %o0, %f0 +END (__copysignf_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_copysignf.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_copysignf.S new file mode 100644 index 0000000000..cd409550de --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_copysignf.S @@ -0,0 +1,12 @@ +#include <sparc-ifunc.h> + +SPARC_ASM_VIS3_IFUNC(copysignf) + +weak_alias (__copysignf, copysignf) + +# undef weak_alias +# define weak_alias(a, b) + +#define __copysignf __copysignf_generic + +#include "../../../fpu/s_copysignf.S" diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fabs-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fabs-vis3.S new file mode 100644 index 0000000000..21078eb00f --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fabs-vis3.S @@ -0,0 +1,26 @@ +/* Float absolute value, sparc32+v9 vis3 version. + Copyright (C) 2011-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> + +ENTRY (__fabs_vis3) + movwtos %o0, %f0 + movwtos %o1, %f1 + retl + fabsd %f0, %f0 +END (__fabs_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fabs.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fabs.S new file mode 100644 index 0000000000..86c63989a4 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fabs.S @@ -0,0 +1,12 @@ +#include <sparc-ifunc.h> + +SPARC_ASM_VIS3_IFUNC(fabs) + +weak_alias (__fabs, fabs) + +# undef weak_alias +# define weak_alias(a, b) + +#define __fabs __fabs_generic + +#include "../s_fabs.S" diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fabsf-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fabsf-vis3.S new file mode 100644 index 0000000000..82816a185e --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fabsf-vis3.S @@ -0,0 +1,26 @@ +/* Float absolute value, sparc32 vis3 version. + Copyright (C) 2006-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2006. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + +ENTRY (__fabsf_vis3) + movwtos %o0, %f0 + retl + fabss %f0, %f0 +END (__fabsf_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fabsf.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fabsf.S new file mode 100644 index 0000000000..0f2e11e01f --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fabsf.S @@ -0,0 +1,12 @@ +#include <sparc-ifunc.h> + +SPARC_ASM_VIS3_IFUNC(fabsf) + +weak_alias (__fabsf, fabsf) + +# undef weak_alias +# define weak_alias(a, b) + +#define __fabsf __fabsf_generic + +#include "../../../fpu/s_fabsf.S" diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdim-vis3.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdim-vis3.c new file mode 100644 index 0000000000..8c3666da7a --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdim-vis3.c @@ -0,0 +1,25 @@ +/* Compute positive difference, sparc 32-bit+v9+vis3. + 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 <math.h> + +#define __fdim __fdim_vis3 +#define declare_mgen_alias(t, f) +#define M_LIBM_NEED_COMPAT(f) 0 + +#include <math/s_fdim.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdim.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdim.c new file mode 100644 index 0000000000..417b8690d6 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdim.c @@ -0,0 +1,33 @@ +/* Compute positive difference, sparc 32-bit. + 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/>. */ + +#ifdef HAVE_AS_VIS3_SUPPORT +# include <sparc-ifunc.h> +# include <math.h> + +extern double __fdim_vis3 (double, double); +extern double __fdim_generic (double, double); + +sparc_libm_ifunc(__fdim, hwcap & HWCAP_SPARC_VIS3 ? __fdim_vis3 : __fdim_generic); +weak_alias (__fdim, fdim) + +# define __fdim __fdim_generic +# define declare_mgen_alias(t, f) +#endif + +#include <math/s_fdim.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdimf-vis3.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdimf-vis3.c new file mode 100644 index 0000000000..a8ae7fa3d9 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdimf-vis3.c @@ -0,0 +1,24 @@ +/* Float compute positive difference, sparc 32-bit+v9+vis3. + 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 <math.h> + +#define __fdimf __fdimf_vis3 +#define declare_mgen_alias(t, f) + +#include <math/s_fdimf.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdimf.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdimf.c new file mode 100644 index 0000000000..cf1dc9ec6c --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdimf.c @@ -0,0 +1,34 @@ +/* Float compute positive difference, sparc 32-bit. + 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/>. */ + +#ifdef HAVE_AS_VIS3_SUPPORT +# include <sparc-ifunc.h> +# include <math.h> + +extern float __fdimf_vis3 (float, float); +extern float __fdimf_generic (float, float); + +sparc_libm_ifunc(__fdimf, hwcap & HWCAP_SPARC_VIS3 ? __fdimf_vis3 : __fdimf_generic); +weak_alias (__fdimf, fdimf) + +# define __fdimf __fdimf_generic +# define declare_mgen_alias(t, f) + +#endif + +#include <math/s_fdimf.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fma-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fma-vis3.S new file mode 100644 index 0000000000..2e7d2111a3 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fma-vis3.S @@ -0,0 +1,31 @@ +/* fma function, sparc32 vis3 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + +ENTRY (__fma_vis3) + movwtos %o0, %f0 + movwtos %o1, %f1 + movwtos %o2, %f2 + movwtos %o3, %f3 + movwtos %o4, %f4 + movwtos %o5, %f5 + retl + fmaddd %f0, %f2, %f4, %f0 +END (__fma_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fma.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fma.c new file mode 100644 index 0000000000..3f2f1622c8 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fma.c @@ -0,0 +1,14 @@ +#ifdef HAVE_AS_VIS3_SUPPORT +# include <sparc-ifunc.h> +# include <math.h> + +extern double __fma_vis3 (double, double, double); +extern double __fma_generic (double, double, double); + +sparc_libm_ifunc(__fma, hwcap & HWCAP_SPARC_FMAF ? __fma_vis3 : __fma_generic); +weak_alias (__fma, fma) + +# define __fma __fma_generic +#endif + +#include <sysdeps/ieee754/dbl-64/s_fma.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fmaf-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fmaf-vis3.S new file mode 100644 index 0000000000..0bd443a094 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fmaf-vis3.S @@ -0,0 +1,28 @@ +/* fmaf function, sparc32 vis3 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + +ENTRY (__fmaf_vis3) + movwtos %o0, %f1 + movwtos %o1, %f3 + movwtos %o2, %f5 + retl + fmadds %f1, %f3, %f5, %f0 +END (__fmaf_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fmaf.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fmaf.c new file mode 100644 index 0000000000..7a273a3b13 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fmaf.c @@ -0,0 +1,14 @@ +#ifdef HAVE_AS_VIS3_SUPPORT +# include <sparc-ifunc.h> +# include <math.h> + +extern float __fmaf_vis3 (float, float, float); +extern float __fmaf_generic (float, float, float); + +sparc_libm_ifunc(__fmaf, hwcap & HWCAP_SPARC_FMAF ? __fmaf_vis3 : __fmaf_generic); +weak_alias (__fmaf, fmaf) + +# define __fmaf __fmaf_generic +#endif + +#include <sysdeps/ieee754/dbl-64/s_fmaf.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_llrint-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_llrint-vis3.S new file mode 100644 index 0000000000..7b8616c97f --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_llrint-vis3.S @@ -0,0 +1,58 @@ +/* llrint(), sparc32 v9 vis3 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + + /* VIS instructions are used to facilitate the formation of + easier constants, and the propagation of the sign bit. */ + +#define TWO_FIFTYTWO 0x43300000 /* 2**52 */ + +#define ZERO %f10 /* 0.0 */ +#define SIGN_BIT %f12 /* -0.0 */ + +ENTRY (__llrint_vis3) + sethi %hi(TWO_FIFTYTWO), %o2 + sllx %o0, 32, %o0 + + or %o0, %o1, %o0 + fzero ZERO + + movxtod %o0, %f0 + sllx %o2, 32, %o2 + fnegd ZERO, SIGN_BIT + + movxtod %o2, %f16 + fabsd %f0, %f14 + + fcmpd %fcc3, %f14, %f16 + + fmovduge %fcc3, ZERO, %f16 + fand %f0, SIGN_BIT, SIGN_BIT + + for %f16, SIGN_BIT, %f16 + faddd %f0, %f16, %f6 + fsubd %f6, %f16, %f0 + fabsd %f0, %f0 + for %f0, SIGN_BIT, %f0 + fdtox %f0, %f4 + movstouw %f4, %o0 + retl + movstouw %f5, %o1 +END (__llrint_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_llrint.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_llrint.S new file mode 100644 index 0000000000..fd23041404 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_llrint.S @@ -0,0 +1,24 @@ +#include <sparc-ifunc.h> +#include <math_ldbl_opt.h> + +SPARC_ASM_VIS3_IFUNC(llrint) + +weak_alias (__llrint, llrint) + +strong_alias (__llrint, __lllrint) +weak_alias (__lllrint, lllrint) + +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __llrint, llrintl, GLIBC_2_1) +#endif + +# undef weak_alias +# define weak_alias(a, b) +# undef strong_alias +# define strong_alias(a, b) +# undef compat_symbol +# define compat_symbol(a, b, c, d) + +#define __llrint __llrint_generic + +#include "../s_llrint.S" diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_llrintf-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_llrintf-vis3.S new file mode 100644 index 0000000000..a3801893c5 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_llrintf-vis3.S @@ -0,0 +1,54 @@ +/* llrintf(), sparc32 v9 vis3 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + + /* VIS instructions are used to facilitate the formation of + easier constants, and the propagation of the sign bit. */ + +#define TWO_TWENTYTHREE 0x4b000000 /* 2**23 */ + +#define ZERO %f10 /* 0.0 */ +#define SIGN_BIT %f12 /* -0.0 */ + +ENTRY (__llrintf_vis3) + movwtos %o0, %f1 + sethi %hi(TWO_TWENTYTHREE), %o2 + fzeros ZERO + + fnegs ZERO, SIGN_BIT + + movwtos %o2, %f16 + fabss %f1, %f14 + + fcmps %fcc3, %f14, %f16 + + fmovsuge %fcc3, ZERO, %f16 + fands %f1, SIGN_BIT, SIGN_BIT + + fors %f16, SIGN_BIT, %f16 + fadds %f1, %f16, %f5 + fsubs %f5, %f16, %f0 + fabss %f0, %f0 + fors %f0, SIGN_BIT, %f0 + fstox %f0, %f4 + movstouw %f4, %o0 + retl + movstouw %f5, %o1 +END (__llrintf_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_llrintf.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_llrintf.S new file mode 100644 index 0000000000..8af5244e7e --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_llrintf.S @@ -0,0 +1,17 @@ +#include <sparc-ifunc.h> + +SPARC_ASM_VIS3_IFUNC(llrintf) + +weak_alias (__llrintf, llrintf) + +strong_alias (__llrintf, __lllrintf) +weak_alias (__lllrintf, lllrintf) + +# undef weak_alias +# define weak_alias(a, b) +# undef strong_alias +# define strong_alias(a, b) + +#define __llrintf __llrintf_generic + +#include "../s_llrintf.S" diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyint-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyint-vis3.S new file mode 100644 index 0000000000..612446b4ae --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyint-vis3.S @@ -0,0 +1,66 @@ +/* Round float to int floating-point values without generating + an inexact exception, sparc32 v9 vis3 version. + + Copyright (C) 2013-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2013. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#include <math_ldbl_opt.h> + + /* We pop constants into the FPU registers using the incoming + argument stack slots, since this avoid having to use any PIC + references. We also thus avoid having to allocate a register + window. + + VIS instructions are used to facilitate the formation of + easier constants, and the propagation of the sign bit. */ + +#define TWO_FIFTYTWO 0x43300000 /* 2**52 */ + +#define ZERO %f10 /* 0.0 */ +#define SIGN_BIT %f12 /* -0.0 */ + +ENTRY (__nearbyint_vis3) + sllx %o0, 32, %o0 + or %o0, %o1, %o0 + movxtod %o0, %f0 + fcmpd %fcc3, %f0, %f0 /* Check for sNaN */ + st %fsr, [%sp + 88] + sethi %hi(TWO_FIFTYTWO), %o2 + sethi %hi(0xf8003e0), %o5 + ld [%sp + 88], %o4 + or %o5, %lo(0xf8003e0), %o5 + andn %o4, %o5, %o4 + fzero ZERO + st %o4, [%sp + 80] + sllx %o2, 32, %o2 + fnegd ZERO, SIGN_BIT + ld [%sp + 80], %fsr + movxtod %o2, %f16 + fabsd %f0, %f14 + fcmpd %fcc3, %f14, %f16 + fmovduge %fcc3, ZERO, %f16 + fand %f0, SIGN_BIT, SIGN_BIT + for %f16, SIGN_BIT, %f16 + faddd %f0, %f16, %f6 + fsubd %f6, %f16, %f0 + fabsd %f0, %f0 + for %f0, SIGN_BIT, %f0 + retl + ld [%sp + 88], %fsr +END (__nearbyint_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyint.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyint.S new file mode 100644 index 0000000000..47da9eaafe --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyint.S @@ -0,0 +1,19 @@ +#include <sparc-ifunc.h> +#include <math_ldbl_opt.h> + +SPARC_ASM_VIS3_IFUNC(nearbyint) + +weak_alias (__nearbyint, nearbyint) + +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __nearbyint, nearbyintl, GLIBC_2_1) +#endif + +# undef weak_alias +# define weak_alias(a, b) +# undef compat_symbol +# define compat_symbol(a, b, c, d) + +#define __nearbyint __nearbyint_generic + +#include "../s_nearbyint.S" diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyintf-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyintf-vis3.S new file mode 100644 index 0000000000..2ac91a01c3 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyintf-vis3.S @@ -0,0 +1,62 @@ +/* Round float to int floating-point values without generating + an inexact exception, sparc32 v9 vis3 version. + + Copyright (C) 2013-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2013. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + + /* We pop constants into the FPU registers using the incoming + argument stack slots, since this avoid having to use any PIC + references. We also thus avoid having to allocate a register + window. + + VIS instructions are used to facilitate the formation of + easier constants, and the propagation of the sign bit. */ + +#define TWO_TWENTYTHREE 0x4b000000 /* 2**23 */ + +#define ZERO %f10 /* 0.0 */ +#define SIGN_BIT %f12 /* -0.0 */ + +ENTRY (__nearbyintf_vis3) + movwtos %o0, %f1 + fcmps %fcc3, %f1, %f1 /* Check for sNaN */ + st %fsr, [%sp + 88] + sethi %hi(TWO_TWENTYTHREE), %o2 + sethi %hi(0xf8003e0), %o5 + ld [%sp + 88], %o4 + fzeros ZERO + or %o5, %lo(0xf8003e0), %o5 + fnegs ZERO, SIGN_BIT + andn %o4, %o5, %o4 + st %o4, [%sp + 80] + ld [%sp + 80], %fsr + movwtos %o2, %f16 + fabss %f1, %f14 + fcmps %fcc3, %f14, %f16 + fmovsuge %fcc3, ZERO, %f16 + fands %f1, SIGN_BIT, SIGN_BIT + fors %f16, SIGN_BIT, %f16 + fadds %f1, %f16, %f5 + fsubs %f5, %f16, %f0 + fabss %f0, %f0 + fors %f0, SIGN_BIT, %f0 + retl + ld [%sp + 88], %fsr +END (__nearbyintf_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyintf.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyintf.S new file mode 100644 index 0000000000..95100c1bfc --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_nearbyintf.S @@ -0,0 +1,12 @@ +#include <sparc-ifunc.h> + +SPARC_ASM_VIS3_IFUNC(nearbyintf) + +weak_alias (__nearbyintf, nearbyintf) + +# undef weak_alias +# define weak_alias(a, b) + +#define __nearbyintf __nearbyintf_generic + +#include "../s_nearbyintf.S" diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_rint-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_rint-vis3.S new file mode 100644 index 0000000000..39cb43706a --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_rint-vis3.S @@ -0,0 +1,55 @@ +/* Round float to int floating-point values, sparc32 v9 vis3 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + + /* VIS instructions are used to facilitate the formation of + easier constants, and the propagation of the sign bit. */ + +#define TWO_FIFTYTWO 0x43300000 /* 2**52 */ + +#define ZERO %f10 /* 0.0 */ +#define SIGN_BIT %f12 /* -0.0 */ + +ENTRY (__rint_vis3) + sethi %hi(TWO_FIFTYTWO), %o2 + sllx %o0, 32, %o0 + + or %o0, %o1, %o0 + fzero ZERO + + movxtod %o0, %f0 + sllx %o2, 32, %o2 + fnegd ZERO, SIGN_BIT + + movxtod %o2, %f16 + fabsd %f0, %f14 + + fcmpd %fcc3, %f14, %f16 + + fmovduge %fcc3, ZERO, %f16 + fand %f0, SIGN_BIT, SIGN_BIT + + for %f16, SIGN_BIT, %f16 + faddd %f0, %f16, %f6 + fsubd %f6, %f16, %f0 + fabsd %f0, %f0 + retl + for %f0, SIGN_BIT, %f0 +END (__rint_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_rint.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_rint.S new file mode 100644 index 0000000000..de893faebf --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_rint.S @@ -0,0 +1,19 @@ +#include <sparc-ifunc.h> +#include <math_ldbl_opt.h> + +SPARC_ASM_VIS3_IFUNC(rint) + +weak_alias (__rint, rint) + +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) +compat_symbol (libm, __rint, rintl, GLIBC_2_0) +#endif + +# undef weak_alias +# define weak_alias(a, b) +# undef compat_symbol +# define compat_symbol(a, b, c, d) + +#define __rint __rint_generic + +#include "../s_rint.S" diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_rintf-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_rintf-vis3.S new file mode 100644 index 0000000000..26c9d82ede --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_rintf-vis3.S @@ -0,0 +1,51 @@ +/* Round float to int floating-point values, sparc32 v9 vis3 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + + /* VIS instructions are used to facilitate the formation of + easier constants, and the propagation of the sign bit. */ + +#define TWO_TWENTYTHREE 0x4b000000 /* 2**23 */ + +#define ZERO %f10 /* 0.0 */ +#define SIGN_BIT %f12 /* -0.0 */ + +ENTRY (__rintf_vis3) + movwtos %o0, %f1 + sethi %hi(TWO_TWENTYTHREE), %o2 + fzeros ZERO + + fnegs ZERO, SIGN_BIT + + movwtos %o2, %f16 + fabss %f1, %f14 + + fcmps %fcc3, %f14, %f16 + + fmovsuge %fcc3, ZERO, %f16 + fands %f1, SIGN_BIT, SIGN_BIT + + fors %f16, SIGN_BIT, %f16 + fadds %f1, %f16, %f5 + fsubs %f5, %f16, %f0 + fabss %f0, %f0 + retl + fors %f0, SIGN_BIT, %f0 +END (__rintf_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_rintf.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_rintf.S new file mode 100644 index 0000000000..38fd936086 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_rintf.S @@ -0,0 +1,12 @@ +#include <sparc-ifunc.h> + +SPARC_ASM_VIS3_IFUNC(rintf) + +weak_alias (__rintf, rintf) + +# undef weak_alias +# define weak_alias(a, b) + +#define __rintf __rintf_generic + +#include "../s_rintf.S" diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/w_sqrt_compat-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/w_sqrt_compat-vis3.S new file mode 100644 index 0000000000..06ff449150 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/w_sqrt_compat-vis3.S @@ -0,0 +1,49 @@ +/* sqrt function. sparc32 v9 vis3 version. + 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/>. */ + +#include <sysdep.h> + +ENTRY (__sqrt_vis3) + movwtos %o0, %f0 + fzero %f8 + movwtos %o1, %f1 + fcmpd %f0, %f8 + fbl 1f + nop +8: retl + fsqrtd %f0, %f0 +1: +#ifdef SHARED + SETUP_PIC_REG_LEAF(o5, g1) + sethi %gdop_hix22(_LIB_VERSION), %g1 + xor %g1, %gdop_lox10(_LIB_VERSION), %g1 + ld [%o5 + %g1], %g1, %gdop(_LIB_VERSION) +#else + sethi %hi(_LIB_VERSION), %g1 + or %g1, %lo(_LIB_VERSION), %g1 +#endif + ld [%g1], %g1 + cmp %g1, -1 + be 8b + mov %o0, %o2 + mov %o1, %o3 + mov 26, %o4 + mov %o7, %g1 + call __kernel_standard + mov %g1, %o7 +END (__sqrt_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/w_sqrt_compat.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/w_sqrt_compat.S new file mode 100644 index 0000000000..1ccac19e29 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/w_sqrt_compat.S @@ -0,0 +1,12 @@ +#include <sparc-ifunc.h> + +SPARC_ASM_VIS3_IFUNC(sqrt) + +weak_alias (__sqrt, sqrt) + +# undef weak_alias +# define weak_alias(a, b) + +#define __sqrt __sqrt_generic + +#include "../w_sqrt_compat.S" diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/w_sqrtf_compat-vis3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/w_sqrtf_compat-vis3.S new file mode 100644 index 0000000000..5b21523fc0 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/w_sqrtf_compat-vis3.S @@ -0,0 +1,47 @@ +/* sqrtf function. sparc32 v9 vis3 version. + 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/>. */ + +#include <sysdep.h> + +ENTRY (__sqrtf_vis3) + movwtos %o0, %f0 + fzeros %f8 + fcmps %f0, %f8 + fbl 1f + nop +8: retl + fsqrts %f0, %f0 +1: +#ifdef SHARED + SETUP_PIC_REG_LEAF(o5, g1) + sethi %gdop_hix22(_LIB_VERSION), %g1 + xor %g1, %gdop_lox10(_LIB_VERSION), %g1 + ld [%o5 + %g1], %g1, %gdop(_LIB_VERSION) +#else + sethi %hi(_LIB_VERSION), %g1 + or %g1, %lo(_LIB_VERSION), %g1 +#endif + ld [%g1], %g1 + cmp %g1, -1 + be 8b + mov %o0, %o1 + mov 126, %o2 + mov %o7, %g1 + call __kernel_standard_f + mov %g1, %o7 +END (__sqrtf_vis3) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/w_sqrtf_compat.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/w_sqrtf_compat.S new file mode 100644 index 0000000000..f0e759a2c8 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/w_sqrtf_compat.S @@ -0,0 +1,12 @@ +#include <sparc-ifunc.h> + +SPARC_ASM_VIS3_IFUNC(sqrtf) + +weak_alias (__sqrtf, sqrtf) + +# undef weak_alias +# define weak_alias(a, b) + +#define __sqrtf __sqrtf_generic + +#include "../w_sqrtf_compat.S" diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_fabs.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_fabs.S new file mode 100644 index 0000000000..bf51739b5a --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_fabs.S @@ -0,0 +1,28 @@ +/* Float absolute value, sparc32+v9 version. + Copyright (C) 2011-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> + +ENTRY (__fabs) + st %o0, [%sp+72] + st %o1, [%sp+76] + ldd [%sp+72], %f0 + retl + fabsd %f0, %f0 +END (__fabs) +weak_alias (__fabs, fabs) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_isnan.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_isnan.S new file mode 100644 index 0000000000..62c4fc3593 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_isnan.S @@ -0,0 +1,40 @@ +/* isnan(). sparc32 v9 version. + 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/>. */ + +#include <sysdep.h> +#include <math_ldbl_opt.h> + +ENTRY (__isnan) + sethi %hi(0x7ff00000), %g1 + sllx %o0, 33, %o0 + sllx %g1, 32, %g1 + srlx %o0, 1, %o0 + or %o0, %o1, %o0 + sub %g1, %o0, %o0 + retl + srlx %o0, 63, %o0 +END (__isnan) +hidden_def (__isnan) +weak_alias (__isnan, isnan) + +#if !IS_IN (libm) +# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) +compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); +compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +# endif +#endif diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_llrint.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_llrint.S new file mode 100644 index 0000000000..62bd9f50c7 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_llrint.S @@ -0,0 +1,72 @@ +/* llrint(), sparc32 v9 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#include <math_ldbl_opt.h> + + /* We pop constants into the FPU registers using the incoming + argument stack slots, since this avoid having to use any PIC + references. We also thus avoid having to allocate a register + window. + + VIS instructions are used to facilitate the formation of + easier constants, and the propagation of the sign bit. */ + +#define TWO_FIFTYTWO 0x43300000 /* 2**52 */ + +#define ZERO %f10 /* 0.0 */ +#define SIGN_BIT %f12 /* -0.0 */ + +ENTRY (__llrint) + sethi %hi(TWO_FIFTYTWO), %o2 + sllx %o0, 32, %o0 + + or %o0, %o1, %o0 + fzero ZERO + + stx %o0, [%sp + 72] + sllx %o2, 32, %o2 + fnegd ZERO, SIGN_BIT + + ldd [%sp + 72], %f0 + + stx %o2, [%sp + 72] + fabsd %f0, %f14 + + ldd [%sp + 72], %f16 + fcmpd %fcc3, %f14, %f16 + + fmovduge %fcc3, ZERO, %f16 + fand %f0, SIGN_BIT, SIGN_BIT + + for %f16, SIGN_BIT, %f16 + faddd %f0, %f16, %f6 + fsubd %f6, %f16, %f0 + fabsd %f0, %f0 + for %f0, SIGN_BIT, %f0 + fdtox %f0, %f4 + std %f4, [%sp + 72] + retl + ldd [%sp + 72], %o0 +END (__llrint) +weak_alias (__llrint, llrint) + +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __llrint, llrintl, GLIBC_2_1) +#endif diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_llrintf.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_llrintf.S new file mode 100644 index 0000000000..cda284b124 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_llrintf.S @@ -0,0 +1,62 @@ +/* llrintf(), sparc32 v9 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + + /* We pop constants into the FPU registers using the incoming + argument stack slots, since this avoid having to use any PIC + references. We also thus avoid having to allocate a register + window. + + VIS instructions are used to facilitate the formation of + easier constants, and the propagation of the sign bit. */ + +#define TWO_TWENTYTHREE 0x4b000000 /* 2**23 */ + +#define ZERO %f10 /* 0.0 */ +#define SIGN_BIT %f12 /* -0.0 */ + +ENTRY (__llrintf) + st %o0, [%sp + 68] + sethi %hi(TWO_TWENTYTHREE), %o2 + fzeros ZERO + + ld [%sp + 68], %f1 + fnegs ZERO, SIGN_BIT + + st %o2, [%sp + 68] + fabss %f1, %f14 + + ld [%sp + 68], %f16 + fcmps %fcc3, %f14, %f16 + + fmovsuge %fcc3, ZERO, %f16 + fands %f1, SIGN_BIT, SIGN_BIT + + fors %f16, SIGN_BIT, %f16 + fadds %f1, %f16, %f5 + fsubs %f5, %f16, %f0 + fabss %f0, %f0 + fors %f0, SIGN_BIT, %f0 + fstox %f0, %f4 + std %f4, [%sp + 72] + retl + ldd [%sp + 72], %o0 +END (__llrintf) +weak_alias (__llrintf, llrintf) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_lrintf.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_lrintf.S new file mode 100644 index 0000000000..a242b755d0 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_lrintf.S @@ -0,0 +1,62 @@ +/* lrintf(), sparc32 v9 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + + /* We pop constants into the FPU registers using the incoming + argument stack slots, since this avoid having to use any PIC + references. We also thus avoid having to allocate a register + window. + + VIS instructions are used to facilitate the formation of + easier constants, and the propagation of the sign bit. */ + +#define TWO_TWENTYTHREE 0x4b000000 /* 2**23 */ + +#define ZERO %f10 /* 0.0 */ +#define SIGN_BIT %f12 /* -0.0 */ + +ENTRY (__lrintf) + st %o0, [%sp + 68] + sethi %hi(TWO_TWENTYTHREE), %o2 + fzeros ZERO + + ld [%sp + 68], %f1 + fnegs ZERO, SIGN_BIT + + st %o2, [%sp + 68] + fabss %f1, %f14 + + ld [%sp + 68], %f16 + fcmps %fcc3, %f14, %f16 + + fmovsuge %fcc3, ZERO, %f16 + fands %f1, SIGN_BIT, SIGN_BIT + + fors %f16, SIGN_BIT, %f16 + fadds %f1, %f16, %f5 + fsubs %f5, %f16, %f0 + fabss %f0, %f0 + fors %f0, SIGN_BIT, %f0 + fstoi %f0, %f3 + st %f3, [%sp + 68] + retl + ld [%sp + 68], %o0 +END (__lrintf) +weak_alias (__lrintf, lrintf) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyint.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyint.S new file mode 100644 index 0000000000..c26d2e3e44 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyint.S @@ -0,0 +1,73 @@ +/* Round float to int floating-point values without generating + an inexact exception, sparc32 v9 version. + + Copyright (C) 2013-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2013. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#include <math_ldbl_opt.h> + + /* We pop constants into the FPU registers using the incoming + argument stack slots, since this avoid having to use any PIC + references. We also thus avoid having to allocate a register + window. + + VIS instructions are used to facilitate the formation of + easier constants, and the propagation of the sign bit. */ + +#define TWO_FIFTYTWO 0x43300000 /* 2**52 */ + +#define ZERO %f10 /* 0.0 */ +#define SIGN_BIT %f12 /* -0.0 */ + +ENTRY (__nearbyint) + sllx %o0, 32, %o0 + or %o0, %o1, %o0 + stx %o0, [%sp + 72] + ldd [%sp + 72], %f0 + fcmpd %fcc3, %f0, %f0 /* Check for sNaN */ + st %fsr, [%sp + 88] + sethi %hi(TWO_FIFTYTWO), %o2 + sethi %hi(0xf8003e0), %o5 + ld [%sp + 88], %o4 + or %o5, %lo(0xf8003e0), %o5 + andn %o4, %o5, %o4 + fzero ZERO + st %o4, [%sp + 80] + sllx %o2, 32, %o2 + fnegd ZERO, SIGN_BIT + ld [%sp + 80], %fsr + stx %o2, [%sp + 72] + fabsd %f0, %f14 + ldd [%sp + 72], %f16 + fcmpd %fcc3, %f14, %f16 + fmovduge %fcc3, ZERO, %f16 + fand %f0, SIGN_BIT, SIGN_BIT + for %f16, SIGN_BIT, %f16 + faddd %f0, %f16, %f6 + fsubd %f6, %f16, %f0 + fabsd %f0, %f0 + for %f0, SIGN_BIT, %f0 + retl + ld [%sp + 88], %fsr +END (__nearbyint) +weak_alias (__nearbyint, nearbyint) + +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __nearbyint, nearbyintl, GLIBC_2_1) +#endif diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyintf.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyintf.S new file mode 100644 index 0000000000..1e65c79ee6 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_nearbyintf.S @@ -0,0 +1,65 @@ +/* Round float to int floating-point values without generating + an inexact exception, sparc32 v9 version. + + Copyright (C) 2013-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2013. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + + /* We pop constants into the FPU registers using the incoming + argument stack slots, since this avoid having to use any PIC + references. We also thus avoid having to allocate a register + window. + + VIS instructions are used to facilitate the formation of + easier constants, and the propagation of the sign bit. */ + +#define TWO_TWENTYTHREE 0x4b000000 /* 2**23 */ + +#define ZERO %f10 /* 0.0 */ +#define SIGN_BIT %f12 /* -0.0 */ + +ENTRY (__nearbyintf) + st %o0, [%sp + 68] + ld [%sp + 68], %f1 + fcmps %fcc3, %f1, %f1 /* Check for sNaN */ + st %fsr, [%sp + 88] + sethi %hi(TWO_TWENTYTHREE), %o2 + sethi %hi(0xf8003e0), %o5 + ld [%sp + 88], %o4 + fzeros ZERO + or %o5, %lo(0xf8003e0), %o5 + fnegs ZERO, SIGN_BIT + andn %o4, %o5, %o4 + st %o4, [%sp + 80] + ld [%sp + 80], %fsr + st %o2, [%sp + 68] + fabss %f1, %f14 + ld [%sp + 68], %f16 + fcmps %fcc3, %f14, %f16 + fmovsuge %fcc3, ZERO, %f16 + fands %f1, SIGN_BIT, SIGN_BIT + fors %f16, SIGN_BIT, %f16 + fadds %f1, %f16, %f5 + fsubs %f5, %f16, %f0 + fabss %f0, %f0 + fors %f0, SIGN_BIT, %f0 + retl + ld [%sp + 88], %fsr +END (__nearbyintf) +weak_alias (__nearbyintf, nearbyintf) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_rint.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_rint.S new file mode 100644 index 0000000000..f3560ccc79 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_rint.S @@ -0,0 +1,69 @@ +/* Round float to int floating-point values, sparc32 v9 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#include <math_ldbl_opt.h> + + /* We pop constants into the FPU registers using the incoming + argument stack slots, since this avoid having to use any PIC + references. We also thus avoid having to allocate a register + window. + + VIS instructions are used to facilitate the formation of + easier constants, and the propagation of the sign bit. */ + +#define TWO_FIFTYTWO 0x43300000 /* 2**52 */ + +#define ZERO %f10 /* 0.0 */ +#define SIGN_BIT %f12 /* -0.0 */ + +ENTRY (__rint) + sethi %hi(TWO_FIFTYTWO), %o2 + sllx %o0, 32, %o0 + + or %o0, %o1, %o0 + fzero ZERO + + stx %o0, [%sp + 72] + sllx %o2, 32, %o2 + fnegd ZERO, SIGN_BIT + + ldd [%sp + 72], %f0 + + stx %o2, [%sp + 72] + fabsd %f0, %f14 + + ldd [%sp + 72], %f16 + fcmpd %fcc3, %f14, %f16 + + fmovduge %fcc3, ZERO, %f16 + fand %f0, SIGN_BIT, SIGN_BIT + + for %f16, SIGN_BIT, %f16 + faddd %f0, %f16, %f6 + fsubd %f6, %f16, %f0 + fabsd %f0, %f0 + retl + for %f0, SIGN_BIT, %f0 +END (__rint) +weak_alias (__rint, rint) + +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) +compat_symbol (libm, __rint, rintl, GLIBC_2_0) +#endif diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_rintf.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_rintf.S new file mode 100644 index 0000000000..dfdae9dcdd --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/s_rintf.S @@ -0,0 +1,59 @@ +/* Round float to int floating-point values, sparc32 v9 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@davemloft.net>, 2012. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + + /* We pop constants into the FPU registers using the incoming + argument stack slots, since this avoid having to use any PIC + references. We also thus avoid having to allocate a register + window. + + VIS instructions are used to facilitate the formation of + easier constants, and the propagation of the sign bit. */ + +#define TWO_TWENTYTHREE 0x4b000000 /* 2**23 */ + +#define ZERO %f10 /* 0.0 */ +#define SIGN_BIT %f12 /* -0.0 */ + +ENTRY (__rintf) + st %o0, [%sp + 68] + sethi %hi(TWO_TWENTYTHREE), %o2 + fzeros ZERO + + ld [%sp + 68], %f1 + fnegs ZERO, SIGN_BIT + + st %o2, [%sp + 68] + fabss %f1, %f14 + + ld [%sp + 68], %f16 + fcmps %fcc3, %f14, %f16 + + fmovsuge %fcc3, ZERO, %f16 + fands %f1, SIGN_BIT, SIGN_BIT + + fors %f16, SIGN_BIT, %f16 + fadds %f1, %f16, %f5 + fsubs %f5, %f16, %f0 + fabss %f0, %f0 + retl + fors %f0, SIGN_BIT, %f0 +END (__rintf) +weak_alias (__rintf, rintf) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/w_sqrt_compat.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/w_sqrt_compat.S new file mode 100644 index 0000000000..4415a82024 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/w_sqrt_compat.S @@ -0,0 +1,51 @@ +/* sqrt function. sparc32 v9 version. + 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/>. */ + +#include <sysdep.h> + +ENTRY (__sqrt) + std %o0, [%sp + 80] + fzero %f8 + ldd [%sp + 80], %f0 + fcmpd %f0, %f8 + fbl 1f + nop +8: retl + fsqrtd %f0, %f0 +1: +#ifdef SHARED + SETUP_PIC_REG_LEAF(o5, g1) + sethi %gdop_hix22(_LIB_VERSION), %g1 + xor %g1, %gdop_lox10(_LIB_VERSION), %g1 + ld [%o5 + %g1], %g1, %gdop(_LIB_VERSION) +#else + sethi %hi(_LIB_VERSION), %g1 + or %g1, %lo(_LIB_VERSION), %g1 +#endif + ld [%g1], %g1 + cmp %g1, -1 + be 8b + mov %o0, %o2 + mov %o1, %o3 + mov 26, %o4 + mov %o7, %g1 + call __kernel_standard + mov %g1, %o7 +END (__sqrt) + +weak_alias (__sqrt, sqrt) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/w_sqrtf_compat.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/w_sqrtf_compat.S new file mode 100644 index 0000000000..1c3c97f8e9 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/fpu/w_sqrtf_compat.S @@ -0,0 +1,50 @@ +/* sqrtf function. sparc32 v9 version. + 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/>. */ + +#include <sysdep.h> + +ENTRY (__sqrtf) + st %o0, [%sp + 72] + fzeros %f8 + ld [%sp + 72], %f0 + fcmps %f0, %f8 + fbl 1f + nop +8: retl + fsqrts %f0, %f0 +1: +#ifdef SHARED + SETUP_PIC_REG_LEAF(o5, g1) + sethi %gdop_hix22(_LIB_VERSION), %g1 + xor %g1, %gdop_lox10(_LIB_VERSION), %g1 + ld [%o5 + %g1], %g1, %gdop(_LIB_VERSION) +#else + sethi %hi(_LIB_VERSION), %g1 + or %g1, %lo(_LIB_VERSION), %g1 +#endif + ld [%g1], %g1 + cmp %g1, -1 + be 8b + mov %o0, %o1 + mov 126, %o2 + mov %o7, %g1 + call __kernel_standard_f + mov %g1, %o7 +END (__sqrtf) + +weak_alias (__sqrtf, sqrtf) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/hp-timing.h b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/hp-timing.h new file mode 100644 index 0000000000..2dfa2d2265 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/hp-timing.h @@ -0,0 +1,36 @@ +/* High precision, low overhead timing functions. sparcv9 version. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller <davem@redhat.com>, 2001. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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 _HP_TIMING_H +#define _HP_TIMING_H 1 + +#define HP_TIMING_AVAIL (1) +#define HP_SMALL_TIMING_AVAIL (1) +#define HP_TIMING_INLINE (1) + +typedef unsigned long long int hp_timing_t; + +#define HP_TIMING_NOW(Var) \ + __asm__ __volatile__ ("rd %%tick, %L0\n\t" \ + "srlx %L0, 32, %H0" \ + : "=r" (Var)) + +#include <hp-timing-common.h> + +#endif /* hp-timing.h */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/memchr.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/memchr.S new file mode 100644 index 0000000000..c5dfbef184 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/memchr.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/memchr.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/memcmp.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/memcmp.S new file mode 100644 index 0000000000..44878f4486 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/memcmp.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/memcmp.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/memcpy.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/memcpy.S new file mode 100644 index 0000000000..675ec496b9 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/memcpy.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/memcpy.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/memset.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/memset.S new file mode 100644 index 0000000000..ac67b7ab7c --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/memset.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/memset.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/mul_1.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/mul_1.S new file mode 100644 index 0000000000..ae4fc17325 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/mul_1.S @@ -0,0 +1,70 @@ +! SPARC v9 32-bit __mpn_mul_1 -- Multiply a limb vector with a single +! limb and store the product in a second limb vector. +! +! Copyright (C) 2013-2017 Free Software Foundation, Inc. +! This file is part of the GNU C Library. +! Contributed by David S. Miller <davem@davemloft.net> +! +! The GNU C Library is free software; you can redistribute it and/or +! modify it under the terms of the GNU Lesser General Public +! License as published by the Free Software Foundation; either +! version 2.1 of the License, or (at your option) any later version. +! +! The GNU C Library is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +! Lesser General Public License for 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> + +#define res_ptr %o0 +#define s1_ptr %o1 +#define sz %o2 +#define s2_limb %o3 +#define carry %o5 +#define tmp1 %g1 +#define tmp2 %g2 +#define tmp3 %g3 +#define tmp4 %o4 + +ENTRY(__mpn_mul_1) + srl sz, 0, sz + srl s2_limb, 0, s2_limb + subcc sz, 1, sz + be,pn %icc, .Lfinal_limb + clr carry + +.Lloop: + lduw [s1_ptr + 0x00], tmp1 + lduw [s1_ptr + 0x04], tmp2 + mulx tmp1, s2_limb, tmp3 + add s1_ptr, 8, s1_ptr + mulx tmp2, s2_limb, tmp4 + sub sz, 2, sz + add res_ptr, 8, res_ptr + add carry, tmp3, tmp3 + stw tmp3, [res_ptr - 0x08] + srlx tmp3, 32, carry + add carry, tmp4, tmp4 + stw tmp4, [res_ptr - 0x04] + brgz sz, .Lloop + srlx tmp4, 32, carry + + brlz,pt sz, .Lfinish + nop + +.Lfinal_limb: + lduw [s1_ptr + 0x00], tmp1 + mulx tmp1, s2_limb, tmp3 + add carry, tmp3, tmp3 + stw tmp3, [res_ptr + 0x00] + srlx tmp3, 32, carry + +.Lfinish: + retl + mov carry, %o0 +END(__mpn_mul_1) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile new file mode 100644 index 0000000000..4ad7aff914 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile @@ -0,0 +1,12 @@ +ifeq ($(subdir),crypt) +libcrypt-sysdep_routines += md5-crop sha256-crop sha512-crop +endif + +ifeq ($(subdir),locale) +localedef-aux += md5-crop +endif + +ifeq ($(subdir),string) +sysdep_routines += memcpy-ultra3 memcpy-niagara1 memcpy-niagara2 \ + memset-niagara1 memcpy-niagara4 memset-niagara4 +endif diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/ifunc-impl-list.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/ifunc-impl-list.c new file mode 100644 index 0000000000..a04aa0f674 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/ifunc-impl-list.c @@ -0,0 +1 @@ +#include <sparc64/multiarch/ifunc-impl-list.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/md5-block.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/md5-block.c new file mode 100644 index 0000000000..3765cabae7 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/md5-block.c @@ -0,0 +1 @@ +#include <sparc64/multiarch/md5-block.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/md5-crop.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/md5-crop.S new file mode 100644 index 0000000000..11a3a81482 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/md5-crop.S @@ -0,0 +1 @@ +#include <sparc64/multiarch/md5-crop.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara1.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara1.S new file mode 100644 index 0000000000..10aef85fe1 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara1.S @@ -0,0 +1,2 @@ +#define XCC icc +#include <sparc64/multiarch/memcpy-niagara1.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara2.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara2.S new file mode 100644 index 0000000000..6b1bf6ea70 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara2.S @@ -0,0 +1,2 @@ +#define XCC icc +#include <sparc64/multiarch/memcpy-niagara2.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara4.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara4.S new file mode 100644 index 0000000000..75ef9c017e --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-niagara4.S @@ -0,0 +1 @@ +#include <sparc64/multiarch/memcpy-niagara4.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-ultra3.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-ultra3.S new file mode 100644 index 0000000000..77adf151aa --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-ultra3.S @@ -0,0 +1,2 @@ +#define XCC icc +#include <sparc64/multiarch/memcpy-ultra3.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy.S new file mode 100644 index 0000000000..14df91e005 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/multiarch/memcpy.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara1.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara1.S new file mode 100644 index 0000000000..b432420876 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara1.S @@ -0,0 +1,2 @@ +#define XCC icc +#include <sparc64/multiarch/memset-niagara1.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara4.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara4.S new file mode 100644 index 0000000000..6545019c46 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara4.S @@ -0,0 +1 @@ +#include <sparc64/multiarch/memset-niagara4.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memset.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memset.S new file mode 100644 index 0000000000..8f8264337d --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/memset.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/multiarch/memset.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/rtld-memcpy.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/rtld-memcpy.c new file mode 100644 index 0000000000..304ad4ef18 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/rtld-memcpy.c @@ -0,0 +1 @@ +#include <sparc64/multiarch/rtld-memcpy.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/rtld-memset.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/rtld-memset.c new file mode 100644 index 0000000000..f24ae880a9 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/rtld-memset.c @@ -0,0 +1 @@ +#include <sparc64/multiarch/rtld-memset.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/sha256-block.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/sha256-block.c new file mode 100644 index 0000000000..600c602b61 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/sha256-block.c @@ -0,0 +1 @@ +#include <sparc64/multiarch/sha256-block.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/sha256-crop.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/sha256-crop.S new file mode 100644 index 0000000000..4895405853 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/sha256-crop.S @@ -0,0 +1 @@ +#include <sparc64/multiarch/sha256-crop.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/sha512-block.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/sha512-block.c new file mode 100644 index 0000000000..7c7c54e5a6 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/sha512-block.c @@ -0,0 +1 @@ +#include <sparc64/multiarch/sha512-block.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/sha512-crop.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/sha512-crop.S new file mode 100644 index 0000000000..cc74a99d3c --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/multiarch/sha512-crop.S @@ -0,0 +1 @@ +#include <sparc64/multiarch/sha512-crop.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_barrier_wait.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_barrier_wait.c new file mode 100644 index 0000000000..246c8d49de --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_barrier_wait.c @@ -0,0 +1 @@ +#include <nptl/pthread_barrier_wait.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_spin_init.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_spin_init.c new file mode 100644 index 0000000000..1eede86abd --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_spin_init.c @@ -0,0 +1 @@ +#include <sysdeps/sparc/sparc64/pthread_spin_init.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_spin_lock.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_spin_lock.S new file mode 100644 index 0000000000..ce53dfa396 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_spin_lock.S @@ -0,0 +1 @@ +#include <sysdeps/sparc/sparc64/pthread_spin_lock.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_spin_trylock.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_spin_trylock.S new file mode 100644 index 0000000000..ffd632da0a --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_spin_trylock.S @@ -0,0 +1 @@ +#include <sysdeps/sparc/sparc64/pthread_spin_trylock.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_spin_unlock.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_spin_unlock.S new file mode 100644 index 0000000000..983c80377a --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/pthread_spin_unlock.S @@ -0,0 +1 @@ +#include <sysdeps/sparc/sparc64/pthread_spin_unlock.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/rawmemchr.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/rawmemchr.S new file mode 100644 index 0000000000..05c269ecc8 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/rawmemchr.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/rawmemchr.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/rem.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/rem.S new file mode 100644 index 0000000000..5385bd8305 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/rem.S @@ -0,0 +1,22 @@ +/* + * Sparc v9 has divide. + * As divx takes 68 cycles and sdivcc only 36, + * we use sdivcc eventhough it is deprecated. + */ + +#include <sysdep.h> + + .text + .align 32 +ENTRY(.rem) + + sra %o0, 31, %o2 + wr %o2, 0, %y + sdivcc %o0, %o1, %o2 + xnor %o2, %g0, %o3 + movvs %icc, %o3, %o2 + smul %o2, %o1, %o2 + retl + sub %o0, %o2, %o0 + +END(.rem) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/rtld-memcpy.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/rtld-memcpy.c new file mode 100644 index 0000000000..6f8386bc76 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/rtld-memcpy.c @@ -0,0 +1 @@ +#include <sparc64/rtld-memcpy.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/rtld-memset.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/rtld-memset.c new file mode 100644 index 0000000000..49b29f5733 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/rtld-memset.c @@ -0,0 +1 @@ +#include <sparc64/rtld-memset.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/sdiv.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/sdiv.S new file mode 100644 index 0000000000..d765514cea --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/sdiv.S @@ -0,0 +1,20 @@ +/* + * Sparc v9 has divide. + * As divx takes 68 cycles and sdivcc only 36, + * we use sdivcc eventhough it is deprecated. + */ + +#include <sysdep.h> + + .text + .align 32 +ENTRY(.div) + + sra %o0, 31, %o2 + wr %o2, 0, %y + sdivcc %o0, %o1, %o0 + xnor %o0, %g0, %o2 + retl + movvs %icc, %o2, %o0 + +END(.div) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/sem_post.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/sem_post.c new file mode 100644 index 0000000000..6a2813caee --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/sem_post.c @@ -0,0 +1 @@ +#include <nptl/sem_post.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/sem_waitcommon.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/sem_waitcommon.c new file mode 100644 index 0000000000..d4a139572b --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/sem_waitcommon.c @@ -0,0 +1 @@ +#include <nptl/sem_waitcommon.c> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/stpcpy.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/stpcpy.S new file mode 100644 index 0000000000..440ad7e215 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/stpcpy.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/stpcpy.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/stpncpy.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/stpncpy.S new file mode 100644 index 0000000000..124136a0b2 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/stpncpy.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/stpncpy.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strcat.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strcat.S new file mode 100644 index 0000000000..7a22235703 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strcat.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/strcat.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strchr.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strchr.S new file mode 100644 index 0000000000..ddd32120d4 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strchr.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/strchr.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strcmp.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strcmp.S new file mode 100644 index 0000000000..5330f4359b --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strcmp.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/strcmp.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strcpy.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strcpy.S new file mode 100644 index 0000000000..0b35c9be08 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strcpy.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/strcpy.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strcspn.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strcspn.S new file mode 100644 index 0000000000..f9d6beabe4 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strcspn.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/strcspn.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strlen.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strlen.S new file mode 100644 index 0000000000..28a216c076 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strlen.S @@ -0,0 +1 @@ +#include <sparc64/strlen.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strncmp.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strncmp.S new file mode 100644 index 0000000000..addd89e05b --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strncmp.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/strncmp.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strncpy.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strncpy.S new file mode 100644 index 0000000000..688f9dfd65 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strncpy.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/strncpy.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strpbrk.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strpbrk.S new file mode 100644 index 0000000000..62294c0af4 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strpbrk.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/strpbrk.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strrchr.c b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strrchr.c new file mode 100644 index 0000000000..ec608d6ab3 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strrchr.c @@ -0,0 +1 @@ +/* strrchr is in strchr.S */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strspn.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strspn.S new file mode 100644 index 0000000000..291e798085 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/strspn.S @@ -0,0 +1,4 @@ +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define XCC icc +#include <sparc64/strspn.S> diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/submul_1.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/submul_1.S new file mode 100644 index 0000000000..52b7d35aa4 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/submul_1.S @@ -0,0 +1,82 @@ +! SPARC v9 32-bit __mpn_submul_1 -- Multiply a limb vector with a limb +! and subtract the result from a second limb vector. +! +! Copyright (C) 2013-2017 Free Software Foundation, Inc. +! This file is part of the GNU C Library. +! Contributed by David S. Miller <davem@davemloft.net> +! +! The GNU C Library is free software; you can redistribute it and/or +! modify it under the terms of the GNU Lesser General Public +! License as published by the Free Software Foundation; either +! version 2.1 of the License, or (at your option) any later version. +! +! The GNU C Library is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +! Lesser General Public License for 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> + +#define res_ptr %i0 +#define s1_ptr %i1 +#define sz_arg %i2 +#define s2l_arg %i3 +#define sz %o4 +#define carry %o5 +#define s2_limb %g1 +#define tmp1 %l0 +#define tmp2 %l1 +#define tmp3 %l2 +#define tmp4 %l3 +#define tmp64_1 %g3 +#define tmp64_2 %o3 + +ENTRY(__mpn_submul_1) + save %sp, -96, %sp + srl sz_arg, 0, sz + srl s2l_arg, 0, s2_limb + subcc sz, 1, sz + be,pn %icc, .Lfinal_limb + subcc %g0, 0, carry + +.Lloop: + lduw [s1_ptr + 0x00], tmp1 + lduw [res_ptr + 0x00], tmp3 + lduw [s1_ptr + 0x04], tmp2 + lduw [res_ptr + 0x04], tmp4 + mulx tmp1, s2_limb, tmp64_1 + add s1_ptr, 8, s1_ptr + mulx tmp2, s2_limb, tmp64_2 + sub sz, 2, sz + add res_ptr, 8, res_ptr + addx carry, tmp64_1, tmp64_1 + srlx tmp64_1, 32, carry + subcc tmp3, tmp64_1, tmp64_1 + stw tmp64_1, [res_ptr - 0x08] + addx carry, tmp64_2, tmp64_2 + srlx tmp64_2, 32, carry + subcc tmp4, tmp64_2, tmp64_2 + brgz sz, .Lloop + stw tmp64_2, [res_ptr - 0x04] + + brlz,pt sz, .Lfinish + nop + +.Lfinal_limb: + lduw [s1_ptr + 0x00], tmp1 + lduw [res_ptr + 0x00], tmp3 + mulx tmp1, s2_limb, tmp64_1 + addx carry, tmp64_1, tmp64_1 + srlx tmp64_1, 32, carry + subcc tmp3, tmp64_1, tmp64_1 + stw tmp64_1, [res_ptr + 0x00] + +.Lfinish: + addx carry, 0, carry + jmpl %i7 + 0x8, %g0 + restore carry, 0, %o0 +END(__mpn_submul_1) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/udiv.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/udiv.S new file mode 100644 index 0000000000..368f85ede2 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/udiv.S @@ -0,0 +1,18 @@ +/* + * Sparc v9 has divide. + * As divx takes 68 cycles and udiv only 37, + * we use udiv eventhough it is deprecated. + */ + +#include <sysdep.h> + + .text + .align 32 +ENTRY(.udiv) + + wr %g0, 0, %y + retl + udiv %o0, %o1, %o0 + +END(.udiv) +strong_alias (.udiv, __wrap_.udiv) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/umul.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/umul.S new file mode 100644 index 0000000000..608b72aca1 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/umul.S @@ -0,0 +1,17 @@ +/* + * Sparc v9 has multiply. + */ + +#include <sysdep.h> + + .text + .align 32 +ENTRY(.umul) + + srl %o0, 0, %o0 + srl %o1, 0, %o1 + mulx %o0, %o1, %o0 + retl + srlx %o0, 32, %o1 + +END(.umul) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/urem.S b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/urem.S new file mode 100644 index 0000000000..cab16c9193 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sparcv9/urem.S @@ -0,0 +1,19 @@ +/* + * Sparc v9 has divide. + * As divx takes 68 cycles and udiv only 37, + * we use udiv eventhough it is deprecated. + */ + +#include <sysdep.h> + + .text + .align 32 +ENTRY(.urem) + + wr %g0, 0, %y + udiv %o0, %o1, %o2 + umul %o2, %o1, %o2 + retl + sub %o0, %o2, %o0 + +END(.urem) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/stackguard-macros.h b/REORG.TODO/sysdeps/sparc/sparc32/stackguard-macros.h new file mode 100644 index 0000000000..1eef0f19f0 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/stackguard-macros.h @@ -0,0 +1,7 @@ +#include <stdint.h> + +#define STACK_CHK_GUARD \ + ({ uintptr_t x; asm ("ld [%%g7+0x14], %0" : "=r" (x)); x; }) + +#define POINTER_CHK_GUARD \ + ({ uintptr_t x; asm ("ld [%%g7+0x18], %0" : "=r" (x)); x; }) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/start.S b/REORG.TODO/sysdeps/sparc/sparc32/start.S new file mode 100644 index 0000000000..a06568d0e9 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/start.S @@ -0,0 +1,99 @@ +/* Startup code for elf32-sparc + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser 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/>. */ + +#include <sysdep.h> + + + .section ".text" + .align 4 + .global _start + .type _start,#function +_start: +#ifdef SHARED + SETUP_PIC_REG(l7) +#endif + + /* Terminate the stack frame, and reserve space for functions to + drop their arguments. */ + mov %g0, %fp + sub %sp, 6*4, %sp + + /* Extract the arguments and environment as encoded on the stack. The + argument info starts after one register window (16 words) past the SP. */ + ld [%sp+22*4], %o1 + add %sp, 23*4, %o2 + + /* Load the addresses of the user entry points. */ +#ifndef SHARED + sethi %hi(main), %o0 + sethi %hi(__libc_csu_init), %o3 + sethi %hi(__libc_csu_fini), %o4 + or %o0, %lo(main), %o0 + or %o3, %lo(__libc_csu_init), %o3 + or %o4, %lo(__libc_csu_fini), %o4 +#else + sethi %gdop_hix22(main), %o0 + sethi %gdop_hix22(__libc_csu_init), %o3 + sethi %gdop_hix22(__libc_csu_fini), %o4 + xor %o0, %gdop_lox10(main), %o0 + xor %o3, %gdop_lox10(__libc_csu_init), %o3 + xor %o4, %gdop_lox10(__libc_csu_fini), %o4 + ld [%l7 + %o0], %o0, %gdop(main) + ld [%l7 + %o3], %o3, %gdop(__libc_csu_init) + ld [%l7 + %o4], %o4, %gdop(__libc_csu_fini) +#endif + + /* When starting a binary via the dynamic linker, %g1 contains the + address of the shared library termination function, which will be + registered with atexit(). If we are statically linked, this will + be NULL. */ + mov %g1, %o5 + + /* Let libc do the rest of the initialization, and call main. */ + call __libc_start_main + nop + + /* Die very horribly if exit returns. */ + unimp + + .size _start, .-_start + +/* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start +__data_start: + .long 0 +weak_alias (__data_start, data_start) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/stpcpy.S b/REORG.TODO/sysdeps/sparc/sparc32/stpcpy.S new file mode 100644 index 0000000000..2cbd69c3b4 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/stpcpy.S @@ -0,0 +1,166 @@ +/* Copy SRC to DEST returning the address of the terminating '\0' in DEST. + For SPARC v7. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by 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 <sysdep.h> + + /* Normally, this uses ((xword - 0x01010101) & 0x80808080) test + to find out if any byte in xword could be zero. This is fast, but + also gives false alarm for any byte in range 0x81-0xff. It does + not matter for correctness, as if this test tells us there could + be some zero byte, we check it byte by byte, but if bytes with + high bits set are common in the strings, then this will give poor + performance. You can #define EIGHTBIT_NOT_RARE and the algorithm + will use one tick slower, but more precise test + ((xword - 0x01010101) & (~xword) & 0x80808080), + which does not give any false alarms (but if some bits are set, + one cannot assume from it which bytes are zero and which are not). + It is yet to be measured, what is the correct default for glibc + in these days for an average user. + */ + + .text + .align 4 + +ENTRY(__stpcpy) + andcc %o1, 3, %g0 + be 20f + sethi %hi(0x80808080), %o4 + + ldub [%o1], %o5 + stb %o5, [%o0] + cmp %o5, 0 + add %o0, 1, %o0 + be 1f + add %o1, 1, %o1 + andcc %o1, 3, %g0 + be 4f + or %o4, %lo(0x80808080), %o3 + ldub [%o1], %o5 + stb %o5, [%o0] + cmp %o5, 0 + add %o0, 1, %o0 + be 1f + add %o1, 1, %o1 + andcc %o1, 3, %g0 + be 5f + sethi %hi(0x01010101), %o4 + ldub [%o1], %o5 + stb %o5, [%o0] + cmp %o5, 0 + add %o0, 1, %o0 + be 1f + add %o1, 1, %o1 + b 6f + or %o4, %lo(0x01010101), %o2 +1: retl + add %o0, -1, %o0 + +20: or %o4, %lo(0x80808080), %o3 +4: sethi %hi(0x01010101), %o4 +5: or %o4, %lo(0x01010101), %o2 +6: andcc %o0, 3, %g0 + bne 16f + sub %g0, 4, %g1 + +11: add %g1, 4, %g1 + ld [%o1 + %g1], %o5 + sub %o5, %o2, %o4 +#ifdef EIGHTBIT_NOT_RARE + andn %o4, %o5, %o4 +#endif + andcc %o4, %o3, %g0 + be,a 11b + st %o5, [%o0 + %g1] + + /* Check every byte. */ + srl %o5, 24, %g5 + andcc %g5, 0xff, %g0 + be 14f + srl %o5, 16, %g5 + andcc %g5, 0xff, %g0 + be 13f + srl %o5, 8, %g5 + andcc %g5, 0xff, %g0 + be 12f + andcc %o5, 0xff, %g0 + bne 11b + st %o5, [%o0 + %g1] + add %o0, %g1, %o0 + retl + add %o0, 3, %o0 +12: srl %o5, 16, %o5 + sth %o5, [%o0 + %g1] + add %g1, 2, %g1 + stb %g0, [%o0 + %g1] + retl + add %o0, %g1, %o0 +13: srl %o5, 16, %o5 + sth %o5, [%o0 + %g1] + add %g1, 1, %g1 + retl + add %o0, %g1, %o0 +14: stb %g0, [%o0 + %g1] + retl + add %o0, %g1, %o0 + +15: srl %o5, 24, %o4 + srl %o5, 16, %g1 + stb %o4, [%o0] + srl %o5, 8, %g4 + stb %g1, [%o0 + 1] + stb %g4, [%o0 + 2] + stb %o5, [%o0 + 3] + add %o0, 4, %o0 +16: ld [%o1], %o5 + sub %o5, %o2, %o4 + andcc %o4, %o3, %g0 + be 15b + add %o1, 4, %o1 + + /* Check every byte. */ + srl %o5, 24, %g5 + andcc %g5, 0xff, %g4 + be 19f + stb %g4, [%o0] + srl %o5, 16, %g5 + andcc %g5, 0xff, %g4 + be 18f + stb %g4, [%o0 + 1] + srl %o5, 8, %g5 + andcc %g5, 0xff, %g4 + be 17f + stb %g4, [%o0 + 2] + andcc %o5, 0xff, %g4 + stb %g4, [%o0 + 3] + bne 16b + add %o0, 4, %o0 + retl + sub %o0, 1, %o0 +17: retl + add %o0, 2, %o0 +18: retl + add %o0, 1, %o0 +19: retl + nop +END(__stpcpy) + +weak_alias (__stpcpy, stpcpy) +libc_hidden_def (__stpcpy) +libc_hidden_builtin_def (stpcpy) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/strcat.S b/REORG.TODO/sysdeps/sparc/sparc32/strcat.S new file mode 100644 index 0000000000..cfa2bbd5b7 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/strcat.S @@ -0,0 +1,352 @@ +/* strcat (dest, src) -- Append SRC on the end of DEST. + For SPARC v7. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by 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 <sysdep.h> + + /* Normally, this uses ((xword - 0x01010101) & 0x80808080) test + to find out if any byte in xword could be zero. This is fast, but + also gives false alarm for any byte in range 0x81-0xff. It does + not matter for correctness, as if this test tells us there could + be some zero byte, we check it byte by byte, but if bytes with + high bits set are common in the strings, then this will give poor + performance. You can #define EIGHTBIT_NOT_RARE and the algorithm + will use one tick slower, but more precise test + ((xword - 0x01010101) & (~xword) & 0x80808080), + which does not give any false alarms (but if some bits are set, + one cannot assume from it which bytes are zero and which are not). + It is yet to be measured, what is the correct default for glibc + in these days for an average user. + */ + + .text + .align 4 + +ENTRY(strcat) + mov %o0, %g2 + andcc %o0, 3, %g0 + be 30f + sethi %hi(0x80808080), %o4 + + ldub [%o0], %o5 + cmp %o5, 0 + be 1f + add %o0, 1, %o0 + andcc %o0, 3, %g0 + be 7f + or %o4, %lo(0x80808080), %o3 + ldub [%o0], %o5 + cmp %o5, 0 + be 2f + add %o0, 1, %o0 + andcc %o0, 3, %g0 + be 8f + sethi %hi(0x01010101), %o4 + ldub [%o0], %o5 + cmp %o5, 0 + be 3f + add %o0, 1, %o0 + b 9f + or %o4, %lo(0x01010101), %o2 +1: or %o4, %lo(0x80808080), %o3 +2: sethi %hi(0x01010101), %o4 +3: or %o4, %lo(0x01010101), %o2 + b 3f + sub %o0, 1, %o0 + +30: or %o4, %lo(0x80808080), %o3 +7: sethi %hi(0x01010101), %o4 +8: or %o4, %lo(0x01010101), %o2 +9: ld [%o0], %o5 +7: sub %o5, %o2, %o4 +#ifdef EIGHTBIT_NOT_RARE + andn %o4, %o5, %o4 +#endif + andcc %o4, %o3, %g0 + be 9b + add %o0, 4, %o0 + + srl %o5, 24, %g5 + andcc %g5, 0xff, %g0 + be 3f + add %o0, -4, %o0 + srl %o5, 16, %g5 + andcc %g5, 0xff, %g0 + be 3f + add %o0, 1, %o0 + srl %o5, 8, %g5 + andcc %g5, 0xff, %g0 + be 3f + add %o0, 1, %o0 + andcc %o5, 0xff, %g0 + add %o0, 2, %o0 + bne,a 7b + ld [%o0], %o5 + sub %o0, 1, %o0 +3: andcc %o1, 3, %o4 + be 4f + nop + + cmp %o4, 2 + be 11f + cmp %o4, 3 + ldub [%o1], %o5 + add %o1, 1, %o1 + stb %o5, [%o0] + be 13f + cmp %o5, 0 + be 0f + add %o0, 1, %o0 +11: lduh [%o1], %o5 + add %o1, 2, %o1 + srl %o5, 8, %o4 + cmp %o4, 0 + stb %o4, [%o0] + bne,a 12f + stb %o5, [%o0 + 1] + retl + mov %g2, %o0 +12: andcc %o5, 0xff, %o5 + bne 4f + add %o0, 2, %o0 + retl + mov %g2, %o0 +13: bne 4f + add %o0, 1, %o0 + retl + mov %g2, %o0 + +4: andcc %o0, 3, %g3 + bne 12f +1: ld [%o1], %o5 + add %o1, 4, %o1 + sub %o5, %o2, %o4 +#ifdef EIGHTBIT_NOT_RARE + andn %o4, %o5, %o4 +#endif + add %o0, 4, %o0 + andcc %o4, %o3, %g0 + be,a 1b + st %o5, [%o0 - 4] + + srl %o5, 24, %g5 + andcc %g5, 0xff, %g0 + be 1f + srl %o5, 16, %g5 + andcc %g5, 0xff, %g0 + be 2f + srl %o5, 8, %g5 + andcc %g5, 0xff, %g0 + be 3f + andcc %o5, 0xff, %g0 + bne 1b + st %o5, [%o0 - 4] + retl + mov %g2, %o0 +3: srl %o5, 16, %o5 + sth %o5, [%o0 - 4] + stb %g0, [%o0 - 2] + retl + mov %g2, %o0 +2: srl %o5, 16, %o5 + sth %o5, [%o0 - 4] + retl + mov %g2, %o0 +1: stb %g0, [%o0 - 4] + retl + mov %g2, %o0 + +12: add %o1, 4, %o1 + sub %o5, %o2, %o4 + cmp %g3, 2 + be 2f + cmp %g3, 3 + be 3f + andcc %o4, %o3, %g0 + bne 5f + srl %o5, 24, %g5 + stb %g5, [%o0] + sub %o0, 1, %o0 + srl %o5, 8, %g5 + sth %g5, [%o0 + 2] +1: add %o0, 4, %o0 +4: sll %o5, 24, %g6 + ld [%o1], %o5 + add %o1, 4, %o1 + srl %o5, 8, %g5 + sub %o5, %o2, %o4 +#ifdef EIGHTBIT_NOT_RARE + andn %o4, %o5, %o4 +#endif + or %g5, %g6, %g5 + andcc %o4, %o3, %g0 + be,a 1b + st %g5, [%o0] + srl %o5, 24, %o4 + andcc %o4, 0xff, %g0 + be 6f + srl %o5, 16, %o4 + andcc %o4, 0xff, %g0 + be 7f + srl %o5, 8, %o4 + st %g5, [%o0] + andcc %o4, 0xff, %g0 + be 0f + andcc %o5, 0xff, %g0 +1: bne 4b + add %o0, 4, %o0 +9: stb %g0, [%o0] +0: retl + mov %g2, %o0 + +6: srl %g5, 16, %g5 + sth %g5, [%o0] + retl + mov %g2, %o0 + +7: srl %g5, 16, %g5 + sth %g5, [%o0] + stb %g0, [%o0 + 2] + retl + mov %g2, %o0 + +5: andcc %g5, 0xff, %g4 + be 9b + srl %o5, 16, %g5 + andcc %g5, 0xff, %g0 + be 7f + srl %o5, 8, %g5 + andcc %g5, 0xff, %g0 + stb %g4, [%o0] + sth %g5, [%o0 + 1] + sub %o0, 1, %o0 + bne 1b + andcc %o5, 0xff, %g0 + retl + mov %g2, %o0 + +7: stb %g4, [%o0] + stb %g0, [%o0 + 1] + retl + mov %g2, %o0 + +2: andcc %o4, %o3, %g0 + bne 5f + srl %o5, 16, %g5 + sth %g5, [%o0] + sub %o0, 2, %o0 +1: add %o0, 4, %o0 +4: sll %o5, 16, %g6 + ld [%o1], %o5 + add %o1, 4, %o1 + srl %o5, 16, %g5 + sub %o5, %o2, %o4 +#ifdef EIGHTBIT_NOT_RARE + andn %o4, %o5, %o4 +#endif + or %g5, %g6, %g5 + andcc %o4, %o3, %g0 + be,a 1b + st %g5, [%o0] + srl %o5, 24, %o4 + andcc %o4, 0xff, %g0 + be 7f + srl %o5, 16, %o4 + st %g5, [%o0] + andcc %o4, 0xff, %g0 + be 0b + srl %o5, 8, %o4 +1: andcc %o4, 0xff, %g0 + be 8f + andcc %o5, 0xff, %g0 + bne 4b + add %o0, 4, %o0 + sth %o5, [%o0] + retl + mov %g2, %o0 + +7: srl %g5, 16, %g5 + sth %g5, [%o0] + stb %g0, [%o0 + 2] + retl + mov %g2, %o0 + +8: stb %g0, [%o0 + 4] + retl + mov %g2, %o0 + +5: srl %o5, 24, %g5 + andcc %g5, 0xff, %g0 + be 9b + srl %o5, 16, %g5 + andcc %g5, 0xff, %g0 + sth %g5, [%o0] + sub %o0, 2, %o0 + bne 1b + srl %o5, 8, %o4 + retl + mov %g2, %o0 + +3: bne 5f + srl %o5, 24, %g5 + stb %g5, [%o0] + sub %o0, 3, %o0 +1: add %o0, 4, %o0 +4: sll %o5, 8, %g6 + ld [%o1], %o5 + add %o1, 4, %o1 + srl %o5, 24, %g5 + sub %o5, %o2, %o4 +#ifdef EIGHTBIT_NOT_RARE + andn %o4, %o5, %o4 +#endif + or %g5, %g6, %g5 + andcc %o4, %o3, %g0 + be 1b + st %g5, [%o0] + srl %o5, 24, %o4 + andcc %o4, 0xff, %g0 + be 0b + srl %o5, 16, %o4 +1: andcc %o4, 0xff, %g0 + be 8b + srl %o5, 8, %o4 + andcc %o4, 0xff, %g0 + be 9f + andcc %o5, 0xff, %g0 + bne 4b + add %o0, 4, %o0 + srl %o5, 8, %o5 + sth %o5, [%o0] + stb %g0, [%o0 + 2] + retl + mov %g2, %o0 +9: srl %o5, 8, %o5 + sth %o5, [%o0 + 4] + retl + mov %g2, %o0 +5: andcc %g5, 0xff, %g0 + stb %g5, [%o0] + sub %o0, 3, %o0 + bne 1b + srl %o5, 16, %o4 + retl + mov %g2, %o0 +END(strcat) +libc_hidden_builtin_def (strcat) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/strchr.S b/REORG.TODO/sysdeps/sparc/sparc32/strchr.S new file mode 100644 index 0000000000..f934473ea8 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/strchr.S @@ -0,0 +1,284 @@ +/* strchr (str, ch) -- Return pointer to first occurrence of CH in STR. + For SPARC v7. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jj@ultra.linux.cz> and + David S. Miller <davem@caip.rutgers.edu>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + + /* Normally, this uses ((xword - 0x01010101) & 0x80808080) test + to find out if any byte in xword could be zero. This is fast, but + also gives false alarm for any byte in range 0x81-0xff. It does + not matter for correctness, as if this test tells us there could + be some zero byte, we check it byte by byte, but if bytes with + high bits set are common in the strings, then this will give poor + performance. You can #define EIGHTBIT_NOT_RARE and the algorithm + will use one tick slower, but more precise test + ((xword - 0x01010101) & (~xword) & 0x80808080), + which does not give any false alarms (but if some bits are set, + one cannot assume from it which bytes are zero and which are not). + It is yet to be measured, what is the correct default for glibc + in these days for an average user. + */ + + .text + .align 4 +ENTRY(strchr) + andcc %o1, 0xff, %o1 + be 12f + sll %o1, 8, %o2 + andcc %o0, 3, %g0 + or %o1, %o2, %o2 + sethi %hi(0x80808080), %o4 + sll %o2, 16, %o3 + be 13f + or %o3, %o2, %g2 + + ldub [%o0], %g4 + cmp %g4, %o1 + be 11f + add %o0, 1, %o0 + cmp %g4, 0 + be 9f + andcc %o0, 3, %g0 + be 4f + or %o4, %lo(0x80808080), %o3 + ldub [%o0], %g4 + cmp %g4, %o1 + be 11f + add %o0, 1, %o0 + cmp %g4, 0 + be 9f + andcc %o0, 3, %g0 + be 5f + sethi %hi(0x01010101), %o5 + ldub [%o0], %g4 + cmp %g4, %o1 + be 11f + add %o0, 1, %o0 + cmp %g4, 0 + be 9f + or %o5, %lo(0x01010101), %o2 + b 6f + ld [%o0], %g4 +11: retl + sub %o0, 1, %o0 + +13: or %o4, %lo(0x80808080), %o3 +4: sethi %hi(0x01010101), %o5 +5: or %o5, %lo(0x01010101), %o2 +7: ld [%o0], %g4 +6: xor %g4, %g2, %g5 + sub %g4, %o2, %o4 +#ifdef EIGHTBIT_NOT_RARE + sub %g5, %o2, %g6 + andn %o4, %g4, %o4 + andn %g6, %g5, %g5 +#else + sub %g5, %o2, %g5 +#endif + or %g5, %o4, %o4 + andcc %o4, %o3, %g0 + be 7b + add %o0, 4, %o0 + + /* Check every byte. */ +8: srl %g4, 24, %g5 +7: andcc %g5, 0xff, %g5 + be 9f + cmp %g5, %o1 + be 4f + srl %g4, 16, %g5 + andcc %g5, 0xff, %g5 + be 9f + cmp %g5, %o1 + be 3f + srl %g4, 8, %g5 + andcc %g5, 0xff, %g5 + be 9f + cmp %g5, %o1 + be 2f + andcc %g4, 0xff, %g5 + be 9f + cmp %g5, %o1 + bne,a 6b + ld [%o0], %g4 + retl + sub %o0, 1, %o0 +2: retl + sub %o0, 2, %o0 +3: retl + sub %o0, 3, %o0 +4: retl + sub %o0, 4, %o0 +9: retl + clr %o0 + +11: ldub [%o0], %o5 + cmp %o5, 0 + be 1f + add %o0, 1, %o0 + andcc %o0, 3, %g0 + be 4f + or %o4, %lo(0x80808080), %o3 + ldub [%o0], %o5 + cmp %o5, 0 + be 1f + add %o0, 1, %o0 + andcc %o0, 3, %g0 + be 5f + sethi %hi(0x01010101), %o4 + ldub [%o0], %o5 + cmp %o5, 0 + be 1f + add %o0, 1, %o0 + b 6f + or %o4, %lo(0x01010101), %o2 +1: retl + sub %o0, 1, %o0 + +12: andcc %o0, 3, %g0 + bne 11b + sethi %hi(0x80808080), %o4 + or %o4, %lo(0x80808080), %o3 +4: sethi %hi(0x01010101), %o4 +5: or %o4, %lo(0x01010101), %o2 +6: ld [%o0], %o5 +7: sub %o5, %o2, %o4 +#ifdef EIGHTBIT_NOT_RARE + andn %o4, %o5, %o4 +#endif + andcc %o4, %o3, %g0 + be 6b + add %o0, 4, %o0 + + /* Check every byte. */ + srl %o5, 24, %g5 + andcc %g5, 0xff, %g0 + be 8f + add %o0, -4, %o4 + srl %o5, 16, %g5 + andcc %g5, 0xff, %g0 + be 8f + add %o4, 1, %o4 + srl %o5, 8, %g5 + andcc %g5, 0xff, %g0 + be 8f + add %o4, 1, %o4 + andcc %o5, 0xff, %g0 + bne,a 7b + ld [%o0], %o5 + add %o4, 1, %o4 +8: retl + mov %o4, %o0 + +13: ldub [%o0], %g4 + cmp %g4, %o1 + add %o0, 1, %o0 + be,a 1f + sub %o0, 1, %o5 + cmp %g4, 0 + be 9f +1: andcc %o0, 3, %g0 + be 4f + or %o4, %lo(0x80808080), %o3 + ldub [%o0], %g4 + cmp %g4, %o1 + add %o0, 1, %o0 + be,a 1f + sub %o0, 1, %o5 + cmp %g4, 0 + be 9f +1: andcc %o0, 3, %g0 + be 5f + sethi %hi(0x01010101), %o4 + ldub [%o0], %g4 + cmp %g4, %o1 + add %o0, 1, %o0 + be,a 1f + sub %o0, 1, %o5 + cmp %g4, 0 + be 9f +1: or %o4, %lo(0x01010101), %o2 + b 7f + ld [%o0], %g4 +END(strchr) + +ENTRY(strrchr) + andcc %o1, 0xff, %o1 + clr %o5 + be 12b + sll %o1, 8, %o2 + andcc %o0, 3, %g0 + or %o1, %o2, %o2 + sethi %hi(0x80808080), %o4 + sll %o2, 16, %o3 + bne 13b + or %o3, %o2, %g2 + or %o4, %lo(0x80808080), %o3 +4: sethi %hi(0x01010101), %o4 +5: or %o4, %lo(0x01010101), %o2 +6: ld [%o0], %g4 +7: xor %g4, %g2, %g5 + sub %g4, %o2, %o4 +#ifdef EIGHTBIT_NOT_RARE + sub %g5, %o2, %g6 + andn %o4, %g4, %o4 + andn %g6, %g5, %g5 +#else + sub %g5, %o2, %g5 +#endif + or %g5, %o4, %o4 + andcc %o4, %o3, %g0 + be 6b + add %o0, 4, %o0 + + /* Check every byte. */ +3: srl %g4, 24, %g5 +8: andcc %g5, 0xff, %g5 + be 9f + cmp %g5, %o1 + be,a 1f + sub %o0, 4, %o5 +1: srl %g4, 16, %g5 + andcc %g5, 0xff, %g5 + be 9f + cmp %g5, %o1 + be,a 1f + sub %o0, 3, %o5 +1: srl %g4, 8, %g5 + andcc %g5, 0xff, %g5 + be 9f + cmp %g5, %o1 + be,a 1f + sub %o0, 2, %o5 +1: andcc %g4, 0xff, %g5 + be 9f + cmp %g5, %o1 + be,a 1f + sub %o0, 1, %o5 +1: b 7b + ld [%o0], %g4 +9: retl + mov %o5, %o0 +END(strrchr) + +weak_alias (strchr, index) +weak_alias (strrchr, rindex) +libc_hidden_builtin_def (strchr) +libc_hidden_builtin_def (strrchr) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/strcmp.S b/REORG.TODO/sysdeps/sparc/sparc32/strcmp.S new file mode 100644 index 0000000000..18e3700dd2 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/strcmp.S @@ -0,0 +1,259 @@ +/* Compare two strings for differences. + For SPARC v7. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by 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 <sysdep.h> + + /* Normally, this uses ((xword - 0x01010101) & 0x80808080) test + to find out if any byte in xword could be zero. This is fast, but + also gives false alarm for any byte in range 0x81-0xff. It does + not matter for correctness, as if this test tells us there could + be some zero byte, we check it byte by byte, but if bytes with + high bits set are common in the strings, then this will give poor + performance. You can #define EIGHTBIT_NOT_RARE and the algorithm + will use one tick slower, but more precise test + ((xword - 0x01010101) & (~xword) & 0x80808080), + which does not give any false alarms (but if some bits are set, + one cannot assume from it which bytes are zero and which are not). + It is yet to be measured, what is the correct default for glibc + in these days for an average user. + */ + + .text + .align 4 + +ENTRY(strcmp) + andcc %o0, 3, %g0 + be 13f + sethi %hi(0x80808080), %g1 + + ldub [%o0], %o4 + add %o0, 1, %o0 + ldub [%o1], %o5 + cmp %o4, 0 + add %o1, 1, %o1 + be 2f + subcc %o4, %o5, %o4 + bne 2f + andcc %o0, 3, %g0 + be 4f + or %g1, %lo(0x80808080), %o3 + ldub [%o0], %o4 + add %o0, 1, %o0 + ldub [%o1], %o5 + cmp %o4, 0 + add %o1, 1, %o1 + be 2f + subcc %o4, %o5, %o4 + bne 2f + andcc %o0, 3, %g0 + be 5f + sethi %hi(0x01010101), %g1 + ldub [%o0], %o4 + add %o0, 1, %o0 + ldub [%o1], %o5 + cmp %o4, 0 + add %o1, 1, %o1 + be 2f + subcc %o4, %o5, %o4 + bne 2f + andcc %o1, 3, %g2 + bne 12f + or %g1, %lo(0x01010101), %o2 + b 1f + ld [%o0], %o4 +2: retl + mov %o4, %o0 + +13: or %g1, %lo(0x80808080), %o3 +4: sethi %hi(0x01010101), %g1 +5: andcc %o1, 3, %g2 + bne 12f + or %g1, %lo(0x01010101), %o2 + +0: ld [%o0], %o4 +1: ld [%o1], %o5 + sub %o4, %o2, %g1 + add %o0, 4, %o0 + cmp %o4, %o5 +#ifdef EIGHTBIT_NOT_RARE + andn %g1, %o4, %g1 +#endif + bne 11f + andcc %g1, %o3, %g0 + be 0b + add %o1, 4, %o1 + + srl %o4, 24, %g4 + andcc %g4, 0xff, %g0 + be 2f + srl %o4, 16, %g4 + andcc %g4, 0xff, %g0 + be 2f + srl %o4, 8, %g4 + andcc %g4, 0xff, %g0 + be 2f + andcc %o4, 0xff, %g0 + bne,a 1b + ld [%o0], %o4 +2: retl + clr %o0 + +11: srl %o4, 24, %g4 + srl %o5, 24, %g5 + andcc %g4, 0xff, %g0 + be 3f + subcc %g4, %g5, %g4 + bne 3f + srl %o5, 16, %g5 + srl %o4, 16, %g4 + andcc %g4, 0xff, %g0 + be 3f + subcc %g4, %g5, %g4 + bne 3f + srl %o5, 8, %g5 + srl %o4, 8, %g4 + andcc %g4, 0xff, %g0 + be 3f + subcc %g4, %g5, %g4 + bne 3f + subcc %o4, %o5, %o4 + retl + mov %o4, %o0 +3: retl + mov %g4, %o0 + +12: save %sp, -64, %sp + ld [%i0], %i4 + sll %g2, 3, %g3 + andn %i1, 3, %i1 + mov 32, %l1 + ld [%i1], %l2 + mov -1, %g6 + add %i1, 4, %i1 + sub %l1, %g3, %l1 + sll %g6, %g3, %g6 + +1: sll %l2, %g3, %g5 + and %i4, %g6, %l3 + sub %i4, %i2, %g1 +#ifdef EIGHTBIT_NOT_RARE + andn %g1, %i4, %g1 +#endif + andcc %g1, %i3, %g1 + bne 3f + cmp %g5, %l3 + bne 2f + add %i0, 4, %i0 + ld [%i1], %l2 + add %i1, 4, %i1 + srl %l2, %l1, %l4 + or %l4, %g5, %l4 + cmp %l4, %i4 + be,a 1b + ld [%i0], %i4 + restore %l4, %g0, %o3 + retl + sub %o4, %o3, %o0 + +2: sll %l2, %g3, %i2 + srl %i4, %g3, %i3 + srl %i2, %g3, %i2 + restore + retl + sub %o3, %o2, %o0 + +3: srl %i4, 24, %g4 + srl %g5, 24, %l6 + andcc %g4, 0xff, %g0 + be 4f + subcc %g4, %l6, %g4 + bne 4f + cmp %g2, 3 + be 6f + srl %i4, 16, %g4 + srl %g5, 16, %l6 + andcc %g4, 0xff, %g0 + be 4f + subcc %g4, %l6, %g4 + bne 4f + cmp %g2, 2 + be 5f + srl %i4, 8, %g4 + srl %g5, 8, %l6 + andcc %g4, 0xff, %g0 + be 4f + subcc %g4, %l6, %g4 + bne 4f + add %i0, 4, %i0 + ld [%i1], %l2 + add %i1, 4, %i1 + srl %l2, 24, %g5 + andcc %i4, 0xff, %g4 + be 4f + subcc %g4, %g5, %g4 + be,a 1b + ld [%i0], %i4 +4: jmpl %i7 + 8, %g0 + restore %g4, %g0, %o0 + +5: ld [%i1], %l2 + add %i1, 4, %i1 + add %i0, 4, %i0 + srl %l2, 24, %l6 + andcc %g4, 0xff, %g4 + be 4b + subcc %g4, %l6, %g4 + bne 4b + srl %l2, 16, %l6 + andcc %i4, 0xff, %g4 + and %l6, 0xff, %l6 + be 4b + subcc %g4, %l6, %g4 + be,a 1b + ld [%i0], %i4 + jmpl %i7 + 8, %g0 + restore %g4, %g0, %o0 + +6: ld [%i1], %l2 + add %i1, 4, %i1 + add %i0, 4, %i0 + srl %l2, 24, %l6 + andcc %g4, 0xff, %g4 + be 4b + subcc %g4, %l6, %g4 + bne 4b + srl %l2, 16, %l6 + srl %i4, 8, %g4 + and %l6, 0xff, %l6 + andcc %g4, 0xff, %g4 + be 4b + subcc %g4, %l6, %g4 + bne 4b + srl %l2, 8, %l6 + andcc %i4, 0xff, %g4 + and %l6, 0xff, %l6 + be 4b + subcc %g4, %l6, %g4 + be,a 1b + ld [%i0], %i4 + jmpl %i7 + 8, %g0 + restore %g4, %g0, %o0 +END(strcmp) +libc_hidden_builtin_def (strcmp) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/strcpy.S b/REORG.TODO/sysdeps/sparc/sparc32/strcpy.S new file mode 100644 index 0000000000..245b78d612 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/strcpy.S @@ -0,0 +1,276 @@ +/* Copy SRC to DEST returning DEST. + For SPARC v7. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by 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 <sysdep.h> + + /* Normally, this uses ((xword - 0x01010101) & 0x80808080) test + to find out if any byte in xword could be zero. This is fast, but + also gives false alarm for any byte in range 0x81-0xff. It does + not matter for correctness, as if this test tells us there could + be some zero byte, we check it byte by byte, but if bytes with + high bits set are common in the strings, then this will give poor + performance. You can #define EIGHTBIT_NOT_RARE and the algorithm + will use one tick slower, but more precise test + ((xword - 0x01010101) & (~xword) & 0x80808080), + which does not give any false alarms (but if some bits are set, + one cannot assume from it which bytes are zero and which are not). + It is yet to be measured, what is the correct default for glibc + in these days for an average user. + */ + + .text + .align 4 + +ENTRY(strcpy) + mov %o0, %g2 + andcc %o1, 3, %g0 + be 10f + sethi %hi(0x80808080), %o4 + + ldub [%o1], %o5 + stb %o5, [%o0] + cmp %o5, 0 + add %o0, 1, %o0 + be 0f + add %o1, 1, %o1 + andcc %o1, 3, %g0 + be 4f + or %o4, %lo(0x80808080), %o3 + ldub [%o1], %o5 + stb %o5, [%o0] + cmp %o5, 0 + add %o0, 1, %o0 + be 0f + add %o1, 1, %o1 + andcc %o1, 3, %g0 + be 5f + sethi %hi(0x01010101), %o4 + ldub [%o1], %o5 + stb %o5, [%o0] + cmp %o5, 0 + add %o0, 1, %o0 + be 0f + add %o1, 1, %o1 + b 6f + andcc %o0, 3, %g3 + +10: or %o4, %lo(0x80808080), %o3 +4: sethi %hi(0x01010101), %o4 +5: andcc %o0, 3, %g3 +6: bne 10f + or %o4, %lo(0x01010101), %o2 +1: ld [%o1], %o5 + add %o1, 4, %o1 + sub %o5, %o2, %o4 + add %o0, 4, %o0 + andcc %o4, %o3, %g0 + be,a 1b + st %o5, [%o0 - 4] + + srl %o5, 24, %g5 + andcc %g5, 0xff, %g0 + be 1f + srl %o5, 16, %g5 + andcc %g5, 0xff, %g0 + be 2f + srl %o5, 8, %g5 + andcc %g5, 0xff, %g0 + be 3f + andcc %o5, 0xff, %g0 + bne 1b + st %o5, [%o0 - 4] + retl + mov %g2, %o0 +3: srl %o5, 16, %o5 + sth %o5, [%o0 - 4] + stb %g0, [%o0 - 2] + retl + mov %g2, %o0 +2: srl %o5, 16, %o5 + sth %o5, [%o0 - 4] + retl + mov %g2, %o0 +1: stb %g0, [%o0 - 4] + retl + mov %g2, %o0 + +10: ld [%o1], %o5 + add %o1, 4, %o1 + sub %o5, %o2, %o4 + cmp %g3, 2 + be 2f + cmp %g3, 3 + be 3f + andcc %o4, %o3, %g0 + bne 5f + srl %o5, 24, %g5 + stb %g5, [%o0] + sub %o0, 1, %o0 + srl %o5, 8, %g5 + sth %g5, [%o0 + 2] +1: add %o0, 4, %o0 +4: sll %o5, 24, %g6 + ld [%o1], %o5 + add %o1, 4, %o1 + srl %o5, 8, %g5 + sub %o5, %o2, %o4 + or %g5, %g6, %g5 + andcc %o4, %o3, %g0 + be,a 1b + st %g5, [%o0] + srl %o5, 24, %o4 + andcc %o4, 0xff, %g0 + be 6f + srl %o5, 16, %o4 + andcc %o4, 0xff, %g0 + be 7f + srl %o5, 8, %o4 + st %g5, [%o0] + andcc %o4, 0xff, %g0 + be 0f + andcc %o5, 0xff, %g0 +1: bne 4b + add %o0, 4, %o0 +9: stb %g0, [%o0] +0: retl + mov %g2, %o0 +6: srl %g5, 16, %g5 + sth %g5, [%o0] + retl + mov %g2, %o0 +7: srl %g5, 16, %g5 + sth %g5, [%o0] + stb %g0, [%o0 + 2] + retl + mov %g2, %o0 +5: andcc %g5, 0xff, %g4 + be 9b + srl %o5, 16, %g5 + andcc %g5, 0xff, %g0 + be 7f + srl %o5, 8, %g5 + andcc %g5, 0xff, %g0 + stb %g4, [%o0] + sth %g5, [%o0 + 1] + sub %o0, 1, %o0 + bne 1b + andcc %o5, 0xff, %g0 + retl + mov %g2, %o0 +7: stb %g4, [%o0] + stb %g0, [%o0 + 1] + retl + mov %g2, %o0 + +2: andcc %o4, %o3, %g0 + bne 5f + srl %o5, 16, %g5 + sth %g5, [%o0] + sub %o0, 2, %o0 +1: add %o0, 4, %o0 +4: sll %o5, 16, %g6 + ld [%o1], %o5 + add %o1, 4, %o1 + srl %o5, 16, %g5 + sub %o5, %o2, %o4 + or %g5, %g6, %g5 + andcc %o4, %o3, %g0 + be,a 1b + st %g5, [%o0] + srl %o5, 24, %o4 + andcc %o4, 0xff, %g0 + be 7f + srl %o5, 16, %o4 + st %g5, [%o0] + andcc %o4, 0xff, %g0 + be 0b + srl %o5, 8, %o4 +1: andcc %o4, 0xff, %g0 + be 8f + andcc %o5, 0xff, %g0 + bne 4b + add %o0, 4, %o0 + sth %o5, [%o0] + retl + mov %g2, %o0 +7: srl %g5, 16, %g5 + sth %g5, [%o0] + stb %g0, [%o0 + 2] + retl + mov %g2, %o0 +8: stb %g0, [%o0 + 4] + retl + mov %g2, %o0 +5: srl %o5, 24, %g5 + andcc %g5, 0xff, %g0 + be 9b + srl %o5, 16, %g5 + andcc %g5, 0xff, %g0 + sth %g5, [%o0] + sub %o0, 2, %o0 + bne 1b + srl %o5, 8, %o4 + retl + mov %g2, %o0 + +3: bne 5f + srl %o5, 24, %g5 + stb %g5, [%o0] + sub %o0, 3, %o0 +1: add %o0, 4, %o0 +4: sll %o5, 8, %g6 + ld [%o1], %o5 + add %o1, 4, %o1 + srl %o5, 24, %g5 + sub %o5, %o2, %o4 + or %g5, %g6, %g5 + andcc %o4, %o3, %g0 + be 1b + st %g5, [%o0] + srl %o5, 24, %o4 + andcc %o4, 0xff, %g0 + be 0b + srl %o5, 16, %o4 +1: andcc %o4, 0xff, %g0 + be 8b + srl %o5, 8, %o4 + andcc %o4, 0xff, %g0 + be 9f + andcc %o5, 0xff, %g0 + bne 4b + add %o0, 4, %o0 + srl %o5, 8, %o5 + sth %o5, [%o0] + stb %g0, [%o0 + 2] + retl + mov %g2, %o0 +9: srl %o5, 8, %o5 + sth %o5, [%o0 + 4] + retl + mov %g2, %o0 +5: andcc %g5, 0xff, %g0 + stb %g5, [%o0] + sub %o0, 3, %o0 + bne 1b + srl %o5, 16, %o4 + retl + mov %g2, %o0 +END(strcpy) +libc_hidden_builtin_def (strcpy) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/strlen.S b/REORG.TODO/sysdeps/sparc/sparc32/strlen.S new file mode 100644 index 0000000000..59baee884e --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/strlen.S @@ -0,0 +1,75 @@ +/* Determine the length of a string. + For SPARC v7. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jj@ultra.linux.cz> and + David S. Miller <davem@davemloft.net>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for 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> + + .text + .align 4 + +ENTRY(strlen) + mov %o0, %o1 + andn %o0, 0x3, %o0 + + ld [%o0], %o5 + and %o1, 0x3, %g1 + mov -1, %g5 + + sethi %hi(0x01010101), %o2 + sll %g1, 3, %g1 + + or %o2, %lo(0x01010101), %o2 + srl %g5, %g1, %g2 + + orn %o5, %g2, %o5 + sll %o2, 7, %o3 +10: add %o0, 4, %o0 + + andn %o3, %o5, %g1 + sub %o5, %o2, %g2 + + andcc %g1, %g2, %g0 + be,a 10b + ld [%o0], %o5 + + srl %o5, 24, %g1 + + andcc %g1, 0xff, %g0 + be 90f + sub %o0, 4, %o0 + + srl %o5, 16, %g2 + + andcc %g2, 0xff, %g0 + be 90f + add %o0, 1, %o0 + + srl %o5, 8, %g1 + + andcc %g1, 0xff, %g0 + be 90f + add %o0, 1, %o0 + + add %o0, 1, %o0 + +90: retl + sub %o0, %o1, %o0 +END(strlen) +libc_hidden_builtin_def (strlen) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/strrchr.c b/REORG.TODO/sysdeps/sparc/sparc32/strrchr.c new file mode 100644 index 0000000000..ec608d6ab3 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/strrchr.c @@ -0,0 +1 @@ +/* strrchr is in strchr.S */ diff --git a/REORG.TODO/sysdeps/sparc/sparc32/sub_n.S b/REORG.TODO/sysdeps/sparc/sparc32/sub_n.S new file mode 100644 index 0000000000..22ca71fa93 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/sub_n.S @@ -0,0 +1,328 @@ +! SPARC __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; see the file COPYING.LIB. If not, +! see <http://www.gnu.org/licenses/>. + + +! INPUT PARAMETERS +#define RES_PTR %o0 +#define S1_PTR %o1 +#define S2_PTR %o2 +#define SIZE %o3 + +#include <sysdep.h> + +ENTRY(__mpn_sub_n) + xor S2_PTR,RES_PTR,%g1 + andcc %g1,4,%g0 + bne LOC(1) ! branch if alignment differs + nop +! ** V1a ** + andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0 + be LOC(v1) ! if no, branch + nop +/* Add least significant limb separately to align RES_PTR and S2_PTR */ + ld [S1_PTR],%g4 + add S1_PTR,4,S1_PTR + ld [S2_PTR],%g2 + add S2_PTR,4,S2_PTR + add SIZE,-1,SIZE + subcc %g4,%g2,%o4 + st %o4,[RES_PTR] + add RES_PTR,4,RES_PTR +LOC(v1): + addx %g0,%g0,%o4 ! save cy in register + cmp SIZE,2 ! if SIZE < 2 ... + bl LOC(end2) ! ... branch to tail code + subcc %g0,%o4,%g0 ! restore cy + + ld [S1_PTR+0],%g4 + addcc SIZE,-10,SIZE + ld [S1_PTR+4],%g1 + ldd [S2_PTR+0],%g2 + blt LOC(fin1) + subcc %g0,%o4,%g0 ! restore cy +/* Add blocks of 8 limbs until less than 8 limbs remain */ +LOC(loop1): + subxcc %g4,%g2,%o4 + ld [S1_PTR+8],%g4 + subxcc %g1,%g3,%o5 + ld [S1_PTR+12],%g1 + ldd [S2_PTR+8],%g2 + std %o4,[RES_PTR+0] + subxcc %g4,%g2,%o4 + ld [S1_PTR+16],%g4 + subxcc %g1,%g3,%o5 + ld [S1_PTR+20],%g1 + ldd [S2_PTR+16],%g2 + std %o4,[RES_PTR+8] + subxcc %g4,%g2,%o4 + ld [S1_PTR+24],%g4 + subxcc %g1,%g3,%o5 + ld [S1_PTR+28],%g1 + ldd [S2_PTR+24],%g2 + std %o4,[RES_PTR+16] + subxcc %g4,%g2,%o4 + ld [S1_PTR+32],%g4 + subxcc %g1,%g3,%o5 + ld [S1_PTR+36],%g1 + ldd [S2_PTR+32],%g2 + std %o4,[RES_PTR+24] + addx %g0,%g0,%o4 ! save cy in register + addcc SIZE,-8,SIZE + add S1_PTR,32,S1_PTR + add S2_PTR,32,S2_PTR + add RES_PTR,32,RES_PTR + bge LOC(loop1) + subcc %g0,%o4,%g0 ! restore cy + +LOC(fin1): + addcc SIZE,8-2,SIZE + blt LOC(end1) + subcc %g0,%o4,%g0 ! restore cy +/* Add blocks of 2 limbs until less than 2 limbs remain */ +LOC(loope1): + subxcc %g4,%g2,%o4 + ld [S1_PTR+8],%g4 + subxcc %g1,%g3,%o5 + ld [S1_PTR+12],%g1 + ldd [S2_PTR+8],%g2 + std %o4,[RES_PTR+0] + addx %g0,%g0,%o4 ! save cy in register + addcc SIZE,-2,SIZE + add S1_PTR,8,S1_PTR + add S2_PTR,8,S2_PTR + add RES_PTR,8,RES_PTR + bge LOC(loope1) + subcc %g0,%o4,%g0 ! restore cy +LOC(end1): + subxcc %g4,%g2,%o4 + subxcc %g1,%g3,%o5 + std %o4,[RES_PTR+0] + addx %g0,%g0,%o4 ! save cy in register + + andcc SIZE,1,%g0 + be LOC(ret1) + subcc %g0,%o4,%g0 ! restore cy +/* Add last limb */ + ld [S1_PTR+8],%g4 + ld [S2_PTR+8],%g2 + subxcc %g4,%g2,%o4 + st %o4,[RES_PTR+8] + +LOC(ret1): + retl + addx %g0,%g0,%o0 ! return carry-out from most sign. limb + +LOC(1): xor S1_PTR,RES_PTR,%g1 + andcc %g1,4,%g0 + bne LOC(2) + nop +! ** V1b ** + andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0 + be LOC(v1b) ! if no, branch + nop +/* Add least significant limb separately to align RES_PTR and S1_PTR */ + ld [S2_PTR],%g4 + add S2_PTR,4,S2_PTR + ld [S1_PTR],%g2 + add S1_PTR,4,S1_PTR + add SIZE,-1,SIZE + subcc %g2,%g4,%o4 + st %o4,[RES_PTR] + add RES_PTR,4,RES_PTR +LOC(v1b): + addx %g0,%g0,%o4 ! save cy in register + cmp SIZE,2 ! if SIZE < 2 ... + bl LOC(end2) ! ... branch to tail code + subcc %g0,%o4,%g0 ! restore cy + + ld [S2_PTR+0],%g4 + addcc SIZE,-10,SIZE + ld [S2_PTR+4],%g1 + ldd [S1_PTR+0],%g2 + blt LOC(fin1b) + subcc %g0,%o4,%g0 ! restore cy +/* Add blocks of 8 limbs until less than 8 limbs remain */ +LOC(loop1b): + subxcc %g2,%g4,%o4 + ld [S2_PTR+8],%g4 + subxcc %g3,%g1,%o5 + ld [S2_PTR+12],%g1 + ldd [S1_PTR+8],%g2 + std %o4,[RES_PTR+0] + subxcc %g2,%g4,%o4 + ld [S2_PTR+16],%g4 + subxcc %g3,%g1,%o5 + ld [S2_PTR+20],%g1 + ldd [S1_PTR+16],%g2 + std %o4,[RES_PTR+8] + subxcc %g2,%g4,%o4 + ld [S2_PTR+24],%g4 + subxcc %g3,%g1,%o5 + ld [S2_PTR+28],%g1 + ldd [S1_PTR+24],%g2 + std %o4,[RES_PTR+16] + subxcc %g2,%g4,%o4 + ld [S2_PTR+32],%g4 + subxcc %g3,%g1,%o5 + ld [S2_PTR+36],%g1 + ldd [S1_PTR+32],%g2 + std %o4,[RES_PTR+24] + addx %g0,%g0,%o4 ! save cy in register + addcc SIZE,-8,SIZE + add S1_PTR,32,S1_PTR + add S2_PTR,32,S2_PTR + add RES_PTR,32,RES_PTR + bge LOC(loop1b) + subcc %g0,%o4,%g0 ! restore cy + +LOC(fin1b): + addcc SIZE,8-2,SIZE + blt LOC(end1b) + subcc %g0,%o4,%g0 ! restore cy +/* Add blocks of 2 limbs until less than 2 limbs remain */ +LOC(loope1b): + subxcc %g2,%g4,%o4 + ld [S2_PTR+8],%g4 + subxcc %g3,%g1,%o5 + ld [S2_PTR+12],%g1 + ldd [S1_PTR+8],%g2 + std %o4,[RES_PTR+0] + addx %g0,%g0,%o4 ! save cy in register + addcc SIZE,-2,SIZE + add S1_PTR,8,S1_PTR + add S2_PTR,8,S2_PTR + add RES_PTR,8,RES_PTR + bge LOC(loope1b) + subcc %g0,%o4,%g0 ! restore cy +LOC(end1b): + subxcc %g2,%g4,%o4 + subxcc %g3,%g1,%o5 + std %o4,[RES_PTR+0] + addx %g0,%g0,%o4 ! save cy in register + + andcc SIZE,1,%g0 + be LOC(ret1b) + subcc %g0,%o4,%g0 ! restore cy +/* Add last limb */ + ld [S2_PTR+8],%g4 + ld [S1_PTR+8],%g2 + subxcc %g2,%g4,%o4 + st %o4,[RES_PTR+8] + +LOC(ret1b): + retl + addx %g0,%g0,%o0 ! return carry-out from most sign. limb + +! ** V2 ** +/* If we come here, the alignment of S1_PTR and RES_PTR as well as the + alignment of S2_PTR and RES_PTR differ. Since there are only two ways + things can be aligned (that we care about) we now know that the alignment + of S1_PTR and S2_PTR are the same. */ + +LOC(2): cmp SIZE,1 + be LOC(jone) + nop + andcc S1_PTR,4,%g0 ! S1_PTR unaligned? Side effect: cy=0 + be LOC(v2) ! if no, branch + nop +/* Add least significant limb separately to align S1_PTR and S2_PTR */ + ld [S1_PTR],%g4 + add S1_PTR,4,S1_PTR + ld [S2_PTR],%g2 + add S2_PTR,4,S2_PTR + add SIZE,-1,SIZE + subcc %g4,%g2,%o4 + st %o4,[RES_PTR] + add RES_PTR,4,RES_PTR + +LOC(v2): + addx %g0,%g0,%o4 ! save cy in register + addcc SIZE,-8,SIZE + blt LOC(fin2) + subcc %g0,%o4,%g0 ! restore cy +/* Add blocks of 8 limbs until less than 8 limbs remain */ +LOC(loop2): + ldd [S1_PTR+0],%g2 + ldd [S2_PTR+0],%o4 + subxcc %g2,%o4,%g2 + st %g2,[RES_PTR+0] + subxcc %g3,%o5,%g3 + st %g3,[RES_PTR+4] + ldd [S1_PTR+8],%g2 + ldd [S2_PTR+8],%o4 + subxcc %g2,%o4,%g2 + st %g2,[RES_PTR+8] + subxcc %g3,%o5,%g3 + st %g3,[RES_PTR+12] + ldd [S1_PTR+16],%g2 + ldd [S2_PTR+16],%o4 + subxcc %g2,%o4,%g2 + st %g2,[RES_PTR+16] + subxcc %g3,%o5,%g3 + st %g3,[RES_PTR+20] + ldd [S1_PTR+24],%g2 + ldd [S2_PTR+24],%o4 + subxcc %g2,%o4,%g2 + st %g2,[RES_PTR+24] + subxcc %g3,%o5,%g3 + st %g3,[RES_PTR+28] + addx %g0,%g0,%o4 ! save cy in register + addcc SIZE,-8,SIZE + add S1_PTR,32,S1_PTR + add S2_PTR,32,S2_PTR + add RES_PTR,32,RES_PTR + bge LOC(loop2) + subcc %g0,%o4,%g0 ! restore cy + +LOC(fin2): + addcc SIZE,8-2,SIZE + blt LOC(end2) + subcc %g0,%o4,%g0 ! restore cy +LOC(loope2): + ldd [S1_PTR+0],%g2 + ldd [S2_PTR+0],%o4 + subxcc %g2,%o4,%g2 + st %g2,[RES_PTR+0] + subxcc %g3,%o5,%g3 + st %g3,[RES_PTR+4] + addx %g0,%g0,%o4 ! save cy in register + addcc SIZE,-2,SIZE + add S1_PTR,8,S1_PTR + add S2_PTR,8,S2_PTR + add RES_PTR,8,RES_PTR + bge LOC(loope2) + subcc %g0,%o4,%g0 ! restore cy +LOC(end2): + andcc SIZE,1,%g0 + be LOC(ret2) + subcc %g0,%o4,%g0 ! restore cy +/* Add last limb */ +LOC(jone): + ld [S1_PTR],%g4 + ld [S2_PTR],%g2 + subxcc %g4,%g2,%o4 + st %o4,[RES_PTR] + +LOC(ret2): + retl + addx %g0,%g0,%o0 ! return carry-out from most sign. limb + +END(__mpn_sub_n) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/submul_1.S b/REORG.TODO/sysdeps/sparc/sparc32/submul_1.S new file mode 100644 index 0000000000..58dd2a3fc6 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/submul_1.S @@ -0,0 +1,146 @@ +! SPARC __mpn_submul_1 -- Multiply a limb vector with a limb and subtract +! the result 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; see the file COPYING.LIB. If not, +! see <http://www.gnu.org/licenses/>. + + +! INPUT PARAMETERS +! RES_PTR o0 +! S1_PTR o1 +! SIZE o2 +! S2_LIMB o3 + +#include <sysdep.h> + +ENTRY(__mpn_submul_1) + ! Make S1_PTR and RES_PTR point at the end of their blocks + ! and put (- 4 x SIZE) in index/loop counter. + sll %o2,2,%o2 + add %o0,%o2,%o4 ! RES_PTR in o4 since o0 is retval + add %o1,%o2,%o1 + sub %g0,%o2,%o2 + + cmp %o3,0xfff + bgu LOC(large) + nop + + ld [%o1+%o2],%o5 + mov 0,%o0 + b LOC(0) + add %o4,-4,%o4 +LOC(loop0): + subcc %o5,%g1,%g1 + ld [%o1+%o2],%o5 + addx %o0,%g0,%o0 + st %g1,[%o4+%o2] +LOC(0): wr %g0,%o3,%y + sra %o5,31,%g2 + and %o3,%g2,%g2 + andcc %g1,0,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,0,%g1 + sra %g1,20,%g4 + sll %g1,12,%g1 + rd %y,%g3 + srl %g3,20,%g3 + or %g1,%g3,%g1 + + addcc %g1,%o0,%g1 + addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb + addcc %o2,4,%o2 ! loop counter + bne LOC(loop0) + ld [%o4+%o2],%o5 + + subcc %o5,%g1,%g1 + addx %o0,%g0,%o0 + retl + st %g1,[%o4+%o2] + + +LOC(large): + ld [%o1+%o2],%o5 + mov 0,%o0 + sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0 + b LOC(1) + add %o4,-4,%o4 +LOC(loop): + subcc %o5,%g3,%g3 + ld [%o1+%o2],%o5 + addx %o0,%g0,%o0 + st %g3,[%o4+%o2] +LOC(1): wr %g0,%o5,%y + and %o5,%g4,%g2 + andcc %g0,%g0,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%g0,%g1 + rd %y,%g3 + addcc %g3,%o0,%g3 + addx %g2,%g1,%o0 + addcc %o2,4,%o2 + bne LOC(loop) + ld [%o4+%o2],%o5 + + subcc %o5,%g3,%g3 + addx %o0,%g0,%o0 + retl + st %g3,[%o4+%o2] + +END(__mpn_submul_1) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/tls-macros.h b/REORG.TODO/sysdeps/sparc/sparc32/tls-macros.h new file mode 100644 index 0000000000..152216e8a8 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/tls-macros.h @@ -0,0 +1,66 @@ +#define TLS_LE(x) \ + ({ int *__l; \ + asm ("sethi %%tle_hix22(" #x "), %0" : "=r" (__l)); \ + asm ("xor %1, %%tle_lox10(" #x "), %0" : "=r" (__l) : "r" (__l)); \ + asm ("add %%g7, %1, %0" : "=r" (__l) : "r" (__l)); \ + __l; }) + +#ifdef __PIC__ +# define TLS_LOAD_PIC \ + ({ register long pc __asm__ ("%o7"); \ + long got; \ + asm ("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" \ + "call .+8\n\t" \ + "add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t" \ + "add %1, %0, %1\n\t" \ + : "=r" (pc), "=r" (got)); \ + got; }) +#else +# define TLS_LOAD_PIC \ + ({ long got; \ + asm (".hidden _GLOBAL_OFFSET_TABLE_\n\t" \ + "sethi %%hi(_GLOBAL_OFFSET_TABLE_), %0\n\t" \ + "or %0, %%lo(_GLOBAL_OFFSET_TABLE_), %0" \ + : "=r" (got)); \ + got; }) +#endif + +#define TLS_IE(x) \ + ({ int *__l; \ + asm ("sethi %%tie_hi22(" #x "), %0" : "=r" (__l)); \ + asm ("add %1, %%tie_lo10(" #x "), %0" : "=r" (__l) : "r" (__l)); \ + asm ("ld [%1 + %2], %0, %%tie_ld(" #x ")" \ + : "=r" (__l) : "r" (TLS_LOAD_PIC), "r" (__l)); \ + asm ("add %%g7, %1, %0, %%tie_add(" #x ")" : "=r" (__l) : "r" (__l)); \ + __l; }) + +#define TLS_LD(x) \ + ({ int *__l; register void *__o0 asm ("%o0"); \ + long __o; \ + asm ("sethi %%tldm_hi22(" #x "), %0" : "=r" (__l)); \ + asm ("add %1, %%tldm_lo10(" #x "), %0" : "=r" (__l) : "r" (__l)); \ + asm ("add %1, %2, %0, %%tldm_add(" #x ")" \ + : "=r" (__o0) : "r" (TLS_LOAD_PIC), "r" (__l)); \ + asm ("call __tls_get_addr, %%tgd_call(" #x ")\n\t" \ + " nop" \ + : "=r" (__o0) : "0" (__o0) \ + : "g1", "g2", "g3", "g4", "g5", "g6", "o1", "o2", "o3", "o4", \ + "o5", "o7", "cc"); \ + asm ("sethi %%tldo_hix22(" #x "), %0" : "=r" (__o)); \ + asm ("xor %1, %%tldo_lox10(" #x "), %0" : "=r" (__o) : "r" (__o)); \ + asm ("add %1, %2, %0, %%tldo_add(" #x ")" : "=r" (__l) \ + : "r" (__o0), "r" (__o)); \ + __l; }) + +#define TLS_GD(x) \ + ({ int *__l; register void *__o0 asm ("%o0"); \ + asm ("sethi %%tgd_hi22(" #x "), %0" : "=r" (__l)); \ + asm ("add %1, %%tgd_lo10(" #x "), %0" : "=r" (__l) : "r" (__l)); \ + asm ("add %1, %2, %0, %%tgd_add(" #x ")" \ + : "=r" (__o0) : "r" (TLS_LOAD_PIC), "r" (__l)); \ + asm ("call __tls_get_addr, %%tgd_call(" #x ")\n\t" \ + " nop" \ + : "=r" (__o0) : "0" (__o0) \ + : "g1", "g2", "g3", "g4", "g5", "g6", "o1", "o2", "o3", "o4", \ + "o5", "o7", "cc"); \ + __o0; }) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/tst-audit.h b/REORG.TODO/sysdeps/sparc/sparc32/tst-audit.h new file mode 100644 index 0000000000..a437dade69 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/tst-audit.h @@ -0,0 +1,25 @@ +/* Definitions for testing PLT entry/exit auditing. SPARC32 version. + + 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 pltenter la_sparc32_gnu_pltenter +#define pltexit la_sparc32_gnu_pltexit +#define La_regs La_sparc32_regs +#define La_retval La_sparc32_retval +#define int_retval lrv_reg[0] diff --git a/REORG.TODO/sysdeps/sparc/sparc32/udiv.S b/REORG.TODO/sysdeps/sparc/sparc32/udiv.S new file mode 100644 index 0000000000..ade0afdf40 --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/udiv.S @@ -0,0 +1,347 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * .udiv name of function to generate + * div div=div => %o0 / %o1; div=rem => %o0 % %o1 + * false false=true => signed; false=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top decade of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + + + +#include <sysdep.h> +#include <sys/trap.h> + +ENTRY(.udiv) + + ! Ready to divide. Compute size of quotient; scale comparand. + orcc %o1, %g0, %o5 + bne 1f + mov %o0, %o3 + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp %o3, %o5 ! if %o1 exceeds %o0, done + blu LOC(got_result) ! (and algorithm fails otherwise) + clr %o2 + sethi %hi(1 << (32 - 4 - 1)), %g1 + cmp %o3, %g1 + blu LOC(not_really_big) + clr %o4 + + ! Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R. + 1: + cmp %o5, %g1 + bgeu 3f + mov 1, %g2 + sll %o5, 4, %o5 + b 1b + add %o4, 1, %o4 + + ! Now compute %g2. + 2: addcc %o5, %o5, %o5 + bcc LOC(not_too_big) + add %g2, 1, %g2 + + ! We get here if the %o1 overflowed while shifting. + ! This means that %o3 has the high-order bit set. + ! Restore %o5 and subtract from %o3. + sll %g1, 4, %g1 ! high order bit + srl %o5, 1, %o5 ! rest of %o5 + add %o5, %g1, %o5 + b LOC(do_single_div) + sub %g2, 1, %g2 + + LOC(not_too_big): + 3: cmp %o5, %o3 + blu 2b + nop + be LOC(do_single_div) + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! %o5 > %o3: went too far: back up 1 step + ! srl %o5, 1, %o5 + ! dec %g2 + ! do single-bit divide steps + ! + ! We have to be careful here. We know that %o3 >= %o5, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + LOC(do_single_div): + subcc %g2, 1, %g2 + bl LOC(end_regular_divide) + nop + sub %o3, %o5, %o3 + mov 1, %o2 + b LOC(end_single_divloop) + nop + LOC(single_divloop): + sll %o2, 1, %o2 + bl 1f + srl %o5, 1, %o5 + ! %o3 >= 0 + sub %o3, %o5, %o3 + b 2f + add %o2, 1, %o2 + 1: ! %o3 < 0 + add %o3, %o5, %o3 + sub %o2, 1, %o2 + 2: + LOC(end_single_divloop): + subcc %g2, 1, %g2 + bge LOC(single_divloop) + tst %o3 + b,a LOC(end_regular_divide) + +LOC(not_really_big): +1: + sll %o5, 4, %o5 + cmp %o5, %o3 + bleu 1b + addcc %o4, 1, %o4 + be LOC(got_result) + sub %o4, 1, %o4 + + tst %o3 ! set up for initial iteration +LOC(divloop): + sll %o2, 4, %o2 + ! depth 1, accumulated bits 0 + bl LOC(1.16) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 2, accumulated bits 1 + bl LOC(2.17) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits 3 + bl LOC(3.19) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 7 + bl LOC(4.23) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (7*2+1), %o2 + +LOC(4.23): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (7*2-1), %o2 + + +LOC(3.19): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 5 + bl LOC(4.21) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (5*2+1), %o2 + +LOC(4.21): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (5*2-1), %o2 + + + +LOC(2.17): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits 1 + bl LOC(3.17) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 3 + bl LOC(4.19) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (3*2+1), %o2 + +LOC(4.19): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (3*2-1), %o2 + + +LOC(3.17): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 1 + bl LOC(4.17) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (1*2+1), %o2 + +LOC(4.17): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (1*2-1), %o2 + + + + +LOC(1.16): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 2, accumulated bits -1 + bl LOC(2.15) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits -1 + bl LOC(3.15) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -1 + bl LOC(4.15) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2+1), %o2 + +LOC(4.15): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2-1), %o2 + + +LOC(3.15): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -3 + bl LOC(4.13) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2+1), %o2 + +LOC(4.13): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2-1), %o2 + + + +LOC(2.15): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits -3 + bl LOC(3.13) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -5 + bl LOC(4.11) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2+1), %o2 + +LOC(4.11): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2-1), %o2 + + +LOC(3.13): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -7 + bl LOC(4.9) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2+1), %o2 + +LOC(4.9): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2-1), %o2 + + + + + 9: +LOC(end_regular_divide): + subcc %o4, 1, %o4 + bge LOC(divloop) + tst %o3 + bl,a LOC(got_result) + ! non-restoring fixup here (one instruction only!) + sub %o2, 1, %o2 + + +LOC(got_result): + + retl + mov %o2, %o0 + +END(.udiv) +strong_alias (.udiv, __wrap_.udiv) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/umul.S b/REORG.TODO/sysdeps/sparc/sparc32/umul.S new file mode 100644 index 0000000000..096554a2bc --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/umul.S @@ -0,0 +1,155 @@ +/* + * Unsigned multiply. Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the + * upper 32 bits of the 64-bit product). + * + * This code optimizes short (less than 13-bit) multiplies. Short + * multiplies require 25 instruction cycles, and long ones require + * 45 instruction cycles. + * + * On return, overflow has occurred (%o1 is not zero) if and only if + * the Z condition code is clear, allowing, e.g., the following: + * + * call .umul + * nop + * bnz overflow (or tnz) + */ + +#include <sysdep.h> + +ENTRY(.umul) + or %o0, %o1, %o4 + mov %o0, %y ! multiplier -> Y + andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args + be LOC(mul_shortway) ! if zero, can do it the short way + andcc %g0, %g0, %o4 ! zero the partial product; clear N & V + + /* + * Long multiply. 32 steps, followed by a final shift step. + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %o1, %o4 ! 13 + mulscc %o4, %o1, %o4 ! 14 + mulscc %o4, %o1, %o4 ! 15 + mulscc %o4, %o1, %o4 ! 16 + mulscc %o4, %o1, %o4 ! 17 + mulscc %o4, %o1, %o4 ! 18 + mulscc %o4, %o1, %o4 ! 19 + mulscc %o4, %o1, %o4 ! 20 + mulscc %o4, %o1, %o4 ! 21 + mulscc %o4, %o1, %o4 ! 22 + mulscc %o4, %o1, %o4 ! 23 + mulscc %o4, %o1, %o4 ! 24 + mulscc %o4, %o1, %o4 ! 25 + mulscc %o4, %o1, %o4 ! 26 + mulscc %o4, %o1, %o4 ! 27 + mulscc %o4, %o1, %o4 ! 28 + mulscc %o4, %o1, %o4 ! 29 + mulscc %o4, %o1, %o4 ! 30 + mulscc %o4, %o1, %o4 ! 31 + mulscc %o4, %o1, %o4 ! 32 + mulscc %o4, %g0, %o4 ! final shift + + /* + * Normally, with the shift-and-add approach, if both numbers are + * positive you get the correct result. With 32-bit two's-complement + * numbers, -x is represented as + * + * x 32 + * ( 2 - ------ ) mod 2 * 2 + * 32 + * 2 + * + * (the `mod 2' subtracts 1 from 1.bbbb). To avoid lots of 2^32s, + * we can treat this as if the radix point were just to the left + * of the sign bit (multiply by 2^32), and get + * + * -x = (2 - x) mod 2 + * + * Then, ignoring the `mod 2's for convenience: + * + * x * y = xy + * -x * y = 2y - xy + * x * -y = 2x - xy + * -x * -y = 4 - 2x - 2y + xy + * + * For signed multiplies, we subtract (x << 32) from the partial + * product to fix this problem for negative multipliers (see mul.s). + * Because of the way the shift into the partial product is calculated + * (N xor V), this term is automatically removed for the multiplicand, + * so we don't have to adjust. + * + * But for unsigned multiplies, the high order bit wasn't a sign bit, + * and the correction is wrong. So for unsigned multiplies where the + * high order bit is one, we end up with xy - (y << 32). To fix it + * we add y << 32. + */ +#if 0 + tst %o1 + bl,a 1f ! if %o1 < 0 (high order bit = 1), + add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half) +1: rd %y, %o0 ! get lower half of product + retl + addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0 +#else + /* Faster code from tege@sics.se. */ + sra %o1, 31, %o2 ! make mask from sign bit + and %o0, %o2, %o2 ! %o2 = 0 or %o0, depending on sign of %o1 + rd %y, %o0 ! get lower half of product + retl + addcc %o4, %o2, %o1 ! add compensation and put upper half in place +#endif + +LOC(mul_shortway): + /* + * Short multiply. 12 steps, followed by a final shift step. + * The resulting bits are off by 12 and (32-12) = 20 bit positions, + * but there is no problem with %o0 being negative (unlike above), + * and overflow is impossible (the answer is at most 24 bits long). + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %g0, %o4 ! final shift + + /* + * %o4 has 20 of the bits that should be in the result; %y has + * the bottom 12 (as %y's top 12). That is: + * + * %o4 %y + * +----------------+----------------+ + * | -12- | -20- | -12- | -20- | + * +------(---------+------)---------+ + * -----result----- + * + * The 12 bits of %o4 left of the `result' area are all zero; + * in fact, all top 20 bits of %o4 are zero. + */ + + rd %y, %o5 + sll %o4, 12, %o0 ! shift middle bits left 12 + srl %o5, 20, %o5 ! shift low bits right 20 + or %o5, %o0, %o0 + retl + addcc %g0, %g0, %o1 ! %o1 = zero, and set Z + +END(.umul) diff --git a/REORG.TODO/sysdeps/sparc/sparc32/urem.S b/REORG.TODO/sysdeps/sparc/sparc32/urem.S new file mode 100644 index 0000000000..d3a1a441fd --- /dev/null +++ b/REORG.TODO/sysdeps/sparc/sparc32/urem.S @@ -0,0 +1,346 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * .urem name of function to generate + * rem rem=div => %o0 / %o1; rem=rem => %o0 % %o1 + * false false=true => signed; false=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top decade of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + + + +#include <sysdep.h> +#include <sys/trap.h> + +ENTRY(.urem) + + ! Ready to divide. Compute size of quotient; scale comparand. + orcc %o1, %g0, %o5 + bne 1f + mov %o0, %o3 + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp %o3, %o5 ! if %o1 exceeds %o0, done + blu LOC(got_result) ! (and algorithm fails otherwise) + clr %o2 + sethi %hi(1 << (32 - 4 - 1)), %g1 + cmp %o3, %g1 + blu LOC(not_really_big) + clr %o4 + + ! Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R. + 1: + cmp %o5, %g1 + bgeu 3f + mov 1, %g2 + sll %o5, 4, %o5 + b 1b + add %o4, 1, %o4 + + ! Now compute %g2. + 2: addcc %o5, %o5, %o5 + bcc LOC(not_too_big) + add %g2, 1, %g2 + + ! We get here if the %o1 overflowed while shifting. + ! This means that %o3 has the high-order bit set. + ! Restore %o5 and subtract from %o3. + sll %g1, 4, %g1 ! high order bit + srl %o5, 1, %o5 ! rest of %o5 + add %o5, %g1, %o5 + b LOC(do_single_div) + sub %g2, 1, %g2 + + LOC(not_too_big): + 3: cmp %o5, %o3 + blu 2b + nop + be LOC(do_single_div) + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! %o5 > %o3: went too far: back up 1 step + ! srl %o5, 1, %o5 + ! dec %g2 + ! do single-bit divide steps + ! + ! We have to be careful here. We know that %o3 >= %o5, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + LOC(do_single_div): + subcc %g2, 1, %g2 + bl LOC(end_regular_divide) + nop + sub %o3, %o5, %o3 + mov 1, %o2 + b LOC(end_single_divloop) + nop + LOC(single_divloop): + sll %o2, 1, %o2 + bl 1f + srl %o5, 1, %o5 + ! %o3 >= 0 + sub %o3, %o5, %o3 + b 2f + add %o2, 1, %o2 + 1: ! %o3 < 0 + add %o3, %o5, %o3 + sub %o2, 1, %o2 + 2: + LOC(end_single_divloop): + subcc %g2, 1, %g2 + bge LOC(single_divloop) + tst %o3 + b,a LOC(end_regular_divide) + +LOC(not_really_big): +1: + sll %o5, 4, %o5 + cmp %o5, %o3 + bleu 1b + addcc %o4, 1, %o4 + be LOC(got_result) + sub %o4, 1, %o4 + + tst %o3 ! set up for initial iteration +LOC(divloop): + sll %o2, 4, %o2 + ! depth 1, accumulated bits 0 + bl LOC(1.16) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 2, accumulated bits 1 + bl LOC(2.17) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits 3 + bl LOC(3.19) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 7 + bl LOC(4.23) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (7*2+1), %o2 + +LOC(4.23): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (7*2-1), %o2 + + +LOC(3.19): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 5 + bl LOC(4.21) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (5*2+1), %o2 + +LOC(4.21): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (5*2-1), %o2 + + + +LOC(2.17): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits 1 + bl LOC(3.17) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 3 + bl LOC(4.19) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (3*2+1), %o2 + +LOC(4.19): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (3*2-1), %o2 + + +LOC(3.17): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 1 + bl LOC(4.17) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (1*2+1), %o2 + +LOC(4.17): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (1*2-1), %o2 + + + + +LOC(1.16): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 2, accumulated bits -1 + bl LOC(2.15) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits -1 + bl LOC(3.15) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -1 + bl LOC(4.15) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2+1), %o2 + +LOC(4.15): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2-1), %o2 + + +LOC(3.15): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -3 + bl LOC(4.13) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2+1), %o2 + +LOC(4.13): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2-1), %o2 + + + +LOC(2.15): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits -3 + bl LOC(3.13) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -5 + bl LOC(4.11) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2+1), %o2 + +LOC(4.11): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2-1), %o2 + + +LOC(3.13): + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -7 + bl LOC(4.9) + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2+1), %o2 + +LOC(4.9): + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2-1), %o2 + + + + + 9: +LOC(end_regular_divide): + subcc %o4, 1, %o4 + bge LOC(divloop) + tst %o3 + bl,a LOC(got_result) + ! non-restoring fixup here (one instruction only!) + add %o3, %o1, %o3 + + +LOC(got_result): + + retl + mov %o3, %o0 + +END(.urem) |