From e207b59ec7cd2c924947cb08cfec90e3ed836d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Thu, 10 Mar 2005 19:04:56 +0000 Subject: [PATCH] added a x86 arch directory for GLibC (based on 2.2.5) git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11645 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../libroot/posix/glibc/arch/x86/Jamfile | 27 ++ .../libroot/posix/glibc/arch/x86/add_n.S | 137 +++++++++++ .../libroot/posix/glibc/arch/x86/addmul_1.S | 89 +++++++ .../libroot/posix/glibc/arch/x86/ldbl2mpn.c | 114 +++++++++ .../libroot/posix/glibc/arch/x86/lshift.S | 232 ++++++++++++++++++ .../libroot/posix/glibc/arch/x86/mul_1.S | 85 +++++++ .../libroot/posix/glibc/arch/x86/rshift.S | 232 ++++++++++++++++++ .../libroot/posix/glibc/arch/x86/sub_n.S | 137 +++++++++++ .../libroot/posix/glibc/arch/x86/submul_1.S | 89 +++++++ 9 files changed, 1142 insertions(+) create mode 100644 src/kernel/libroot/posix/glibc/arch/x86/Jamfile create mode 100644 src/kernel/libroot/posix/glibc/arch/x86/add_n.S create mode 100644 src/kernel/libroot/posix/glibc/arch/x86/addmul_1.S create mode 100644 src/kernel/libroot/posix/glibc/arch/x86/ldbl2mpn.c create mode 100644 src/kernel/libroot/posix/glibc/arch/x86/lshift.S create mode 100644 src/kernel/libroot/posix/glibc/arch/x86/mul_1.S create mode 100644 src/kernel/libroot/posix/glibc/arch/x86/rshift.S create mode 100644 src/kernel/libroot/posix/glibc/arch/x86/sub_n.S create mode 100644 src/kernel/libroot/posix/glibc/arch/x86/submul_1.S diff --git a/src/kernel/libroot/posix/glibc/arch/x86/Jamfile b/src/kernel/libroot/posix/glibc/arch/x86/Jamfile new file mode 100644 index 0000000000..c250c2d03b --- /dev/null +++ b/src/kernel/libroot/posix/glibc/arch/x86/Jamfile @@ -0,0 +1,27 @@ +SubDir OBOS_TOP src kernel libroot posix glibc arch x86 ; + +SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc include arch $(OBOS_ARCH) ; +SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc include ; +SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc stdlib ; +SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc ; + +KernelMergeObject posix_gnu_arch_$(OBOS_ARCH).o : + add_n.S + addmul_1.S + cmp.c + dbl2mpn.c + divrem.c + ldbl2mpn.c + mul.c + mul_1.S + mul_n.c + lshift.S + rshift.S + sub_n.S + submul_1.S + : -fPIC -DPIC + ; + +SEARCH on [ FGristFiles + cmp.c divrem.c mul.c mul_n.c dbl2mpn.c + ] = [ FDirName $(OBOS_TOP) src kernel libroot posix glibc arch ] ; diff --git a/src/kernel/libroot/posix/glibc/arch/x86/add_n.S b/src/kernel/libroot/posix/glibc/arch/x86/add_n.S new file mode 100644 index 0000000000..c2afc37ee3 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/arch/x86/add_n.S @@ -0,0 +1,137 @@ +/* Pentium __mpn_add_n -- Add two limb vectors of the same length > 0 and store + sum in a third limb vector. + Copyright (C) 1992, 94, 95, 96, 97, 98, 2000 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, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" +#include "bp-sym.h" +#include "bp-asm.h" + +#define PARMS LINKAGE+16 /* space for 4 saved regs */ +#define RES PARMS +#define S1 RES+PTR_SIZE +#define S2 S1+PTR_SIZE +#define SIZE S2+PTR_SIZE + + .text +ENTRY (BP_SYM (__mpn_add_n)) + ENTER + + pushl %edi + pushl %esi + pushl %ebp + pushl %ebx + + movl RES(%esp),%edi + movl S1(%esp),%esi + movl S2(%esp),%ebx + movl SIZE(%esp),%ecx +#if __BOUNDED_POINTERS__ + shll $2, %ecx /* convert limbs to bytes */ + CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ecx) + CHECK_BOUNDS_BOTH_WIDE (%esi, S1(%esp), %ecx) + CHECK_BOUNDS_BOTH_WIDE (%ebx, S2(%esp), %ecx) + shrl $2, %ecx +#endif + movl (%ebx),%ebp + + decl %ecx + movl %ecx,%edx + shrl $3,%ecx + andl $7,%edx + testl %ecx,%ecx /* zero carry flag */ + jz L(end) + pushl %edx + + ALIGN (3) +L(oop): movl 28(%edi),%eax /* fetch destination cache line */ + leal 32(%edi),%edi + +L(1): movl (%esi),%eax + movl 4(%esi),%edx + adcl %ebp,%eax + movl 4(%ebx),%ebp + adcl %ebp,%edx + movl 8(%ebx),%ebp + movl %eax,-32(%edi) + movl %edx,-28(%edi) + +L(2): movl 8(%esi),%eax + movl 12(%esi),%edx + adcl %ebp,%eax + movl 12(%ebx),%ebp + adcl %ebp,%edx + movl 16(%ebx),%ebp + movl %eax,-24(%edi) + movl %edx,-20(%edi) + +L(3): movl 16(%esi),%eax + movl 20(%esi),%edx + adcl %ebp,%eax + movl 20(%ebx),%ebp + adcl %ebp,%edx + movl 24(%ebx),%ebp + movl %eax,-16(%edi) + movl %edx,-12(%edi) + +L(4): movl 24(%esi),%eax + movl 28(%esi),%edx + adcl %ebp,%eax + movl 28(%ebx),%ebp + adcl %ebp,%edx + movl 32(%ebx),%ebp + movl %eax,-8(%edi) + movl %edx,-4(%edi) + + leal 32(%esi),%esi + leal 32(%ebx),%ebx + decl %ecx + jnz L(oop) + + popl %edx +L(end): + decl %edx /* test %edx w/o clobbering carry */ + js L(end2) + incl %edx +L(oop2): + leal 4(%edi),%edi + movl (%esi),%eax + adcl %ebp,%eax + movl 4(%ebx),%ebp + movl %eax,-4(%edi) + leal 4(%esi),%esi + leal 4(%ebx),%ebx + decl %edx + jnz L(oop2) +L(end2): + movl (%esi),%eax + adcl %ebp,%eax + movl %eax,(%edi) + + sbbl %eax,%eax + negl %eax + + popl %ebx + popl %ebp + popl %esi + popl %edi + + LEAVE + ret +END (BP_SYM (__mpn_add_n)) diff --git a/src/kernel/libroot/posix/glibc/arch/x86/addmul_1.S b/src/kernel/libroot/posix/glibc/arch/x86/addmul_1.S new file mode 100644 index 0000000000..9329637fe2 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/arch/x86/addmul_1.S @@ -0,0 +1,89 @@ +/* Pentium __mpn_addmul_1 -- Multiply a limb vector with a limb and add + the result to a second limb vector. + Copyright (C) 1992, 94, 96, 97, 98, 00 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, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" +#include "bp-sym.h" +#include "bp-asm.h" + +#define PARMS LINKAGE+16 /* space for 4 saved regs */ +#define RES PARMS +#define S1 RES+PTR_SIZE +#define SIZE S1+PTR_SIZE +#define S2LIMB SIZE+4 + +#define res_ptr edi +#define s1_ptr esi +#define size ecx +#define s2_limb ebx + + .text +ENTRY (BP_SYM (__mpn_addmul_1)) + ENTER + + pushl %edi + pushl %esi + pushl %ebp + pushl %ebx + + movl RES(%esp), %res_ptr + movl S1(%esp), %s1_ptr + movl SIZE(%esp), %size + movl S2LIMB(%esp), %s2_limb +#if __BOUNDED_POINTERS__ + shll $2, %size /* convert limbs to bytes */ + CHECK_BOUNDS_BOTH_WIDE (%res_ptr, RES(%esp), %size) + CHECK_BOUNDS_BOTH_WIDE (%s1_ptr, S1(%esp), %size) + shrl $2, %size +#endif + leal (%res_ptr,%size,4), %res_ptr + leal (%s1_ptr,%size,4), %s1_ptr + negl %size + xorl %ebp, %ebp + ALIGN (3) + +L(oop): adcl $0, %ebp + movl (%s1_ptr,%size,4), %eax + + mull %s2_limb + + addl %ebp, %eax + movl (%res_ptr,%size,4), %ebp + + adcl $0, %edx + addl %eax, %ebp + + movl %ebp, (%res_ptr,%size,4) + incl %size + + movl %edx, %ebp + jnz L(oop) + + adcl $0, %ebp + movl %ebp, %eax + popl %ebx + popl %ebp + popl %esi + popl %edi + + LEAVE + ret +#undef size +END (BP_SYM (__mpn_addmul_1)) diff --git a/src/kernel/libroot/posix/glibc/arch/x86/ldbl2mpn.c b/src/kernel/libroot/posix/glibc/arch/x86/ldbl2mpn.c new file mode 100644 index 0000000000..bf4e4ff43f --- /dev/null +++ b/src/kernel/libroot/posix/glibc/arch/x86/ldbl2mpn.c @@ -0,0 +1,114 @@ +/* Copyright (C) 1995, 1996, 1997, 2000 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "longlong.h" +#include "ieee754.h" +#include +#include + +/* Convert a `long double' in IEEE854 standard double-precision format to a + multi-precision integer representing the significand scaled up by its + number of bits (64 for long double) and an integral power of two + (MPN frexpl). */ + +mp_size_t +__mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size, + int *expt, int *is_neg, + long double value) +{ + union ieee854_long_double u; + u.d = value; + + *is_neg = u.ieee.negative; + *expt = (int) u.ieee.exponent - IEEE854_LONG_DOUBLE_BIAS; + +#if BITS_PER_MP_LIMB == 32 + res_ptr[0] = u.ieee.mantissa1; /* Low-order 32 bits of fraction. */ + res_ptr[1] = u.ieee.mantissa0; /* High-order 32 bits. */ + #define N 2 +#elif BITS_PER_MP_LIMB == 64 + /* Hopefully the compiler will combine the two bitfield extracts + and this composition into just the original quadword extract. */ + res_ptr[0] = ((unsigned long int) u.ieee.mantissa0 << 32) | u.ieee.mantissa1; + #define N 1 +#else + #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" +#endif + + if (u.ieee.exponent == 0) + { + /* A biased exponent of zero is a special case. + Either it is a zero or it is a denormal number. */ + if (res_ptr[0] == 0 && res_ptr[N - 1] == 0) /* Assumes N<=2. */ + /* It's zero. */ + *expt = 0; + else + { + /* It is a denormal number, meaning it has no implicit leading + one bit, and its exponent is in fact the format minimum. */ + int cnt; + + /* One problem with Intel's 80-bit format is that the explicit + leading one in the normalized representation has to be zero + for denormalized number. If it is one, the number is according + to Intel's specification an invalid number. We make the + representation unique by explicitly clearing this bit. */ + res_ptr[N - 1] &= ~(1L << ((LDBL_MANT_DIG - 1) % BITS_PER_MP_LIMB)); + + if (res_ptr[N - 1] != 0) + { + count_leading_zeros (cnt, res_ptr[N - 1]); + if (cnt != 0) + { +#if N == 2 + res_ptr[N - 1] = res_ptr[N - 1] << cnt + | (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt)); + res_ptr[0] <<= cnt; +#else + res_ptr[N - 1] <<= cnt; +#endif + } + *expt = LDBL_MIN_EXP - 1 - cnt; + } + else if (res_ptr[0] != 0) + { + count_leading_zeros (cnt, res_ptr[0]); + res_ptr[N - 1] = res_ptr[0] << cnt; + res_ptr[0] = 0; + *expt = LDBL_MIN_EXP - 1 - BITS_PER_MP_LIMB - cnt; + } + else + { + /* This is the special case of the pseudo denormal number + with only the implicit leading bit set. The value is + in fact a normal number and so we have to treat this + case differently. */ +#if N == 2 + res_ptr[N - 1] = 0x80000000ul; +#else + res_ptr[0] = 0x8000000000000000ul; +#endif + *expt = LDBL_MIN_EXP - 1; + } + } + } + + return N; +} diff --git a/src/kernel/libroot/posix/glibc/arch/x86/lshift.S b/src/kernel/libroot/posix/glibc/arch/x86/lshift.S new file mode 100644 index 0000000000..59d587934e --- /dev/null +++ b/src/kernel/libroot/posix/glibc/arch/x86/lshift.S @@ -0,0 +1,232 @@ +/* Pentium optimized __mpn_lshift -- + Copyright (C) 1992, 94, 95, 96, 97, 98, 2000 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" +#include "bp-sym.h" +#include "bp-asm.h" + +#define PARMS LINKAGE+16 /* space for 4 saved regs */ +#define RES PARMS +#define S RES+PTR_SIZE +#define SIZE S+PTR_SIZE +#define CNT SIZE+4 + + .text +ENTRY (BP_SYM (__mpn_lshift)) + ENTER + + pushl %edi + pushl %esi + pushl %ebp + pushl %ebx + + movl RES(%esp),%edi + movl S(%esp),%esi + movl SIZE(%esp),%ebx + movl CNT(%esp),%ecx +#if __BOUNDED_POINTERS__ + shll $2, %ebx /* convert limbs to bytes */ + CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ebx) + CHECK_BOUNDS_BOTH_WIDE (%esi, S(%esp), %ebx) + shrl $2, %ebx +#endif + +/* We can use faster code for shift-by-1 under certain conditions. */ + cmp $1,%ecx + jne L(normal) + leal 4(%esi),%eax + cmpl %edi,%eax + jnc L(special) /* jump if s_ptr + 1 >= res_ptr */ + leal (%esi,%ebx,4),%eax + cmpl %eax,%edi + jnc L(special) /* jump if res_ptr >= s_ptr + size */ + +L(normal): + leal -4(%edi,%ebx,4),%edi + leal -4(%esi,%ebx,4),%esi + + movl (%esi),%edx + subl $4,%esi + xorl %eax,%eax + shldl %cl,%edx,%eax /* compute carry limb */ + pushl %eax /* push carry limb onto stack */ + + decl %ebx + pushl %ebx + shrl $3,%ebx + jz L(end) + + movl (%edi),%eax /* fetch destination cache line */ + + ALIGN (2) +L(oop): movl -28(%edi),%eax /* fetch destination cache line */ + movl %edx,%ebp + + movl (%esi),%eax + movl -4(%esi),%edx + shldl %cl,%eax,%ebp + shldl %cl,%edx,%eax + movl %ebp,(%edi) + movl %eax,-4(%edi) + + movl -8(%esi),%ebp + movl -12(%esi),%eax + shldl %cl,%ebp,%edx + shldl %cl,%eax,%ebp + movl %edx,-8(%edi) + movl %ebp,-12(%edi) + + movl -16(%esi),%edx + movl -20(%esi),%ebp + shldl %cl,%edx,%eax + shldl %cl,%ebp,%edx + movl %eax,-16(%edi) + movl %edx,-20(%edi) + + movl -24(%esi),%eax + movl -28(%esi),%edx + shldl %cl,%eax,%ebp + shldl %cl,%edx,%eax + movl %ebp,-24(%edi) + movl %eax,-28(%edi) + + subl $32,%esi + subl $32,%edi + decl %ebx + jnz L(oop) + +L(end): popl %ebx + andl $7,%ebx + jz L(end2) +L(oop2): + movl (%esi),%eax + shldl %cl,%eax,%edx + movl %edx,(%edi) + movl %eax,%edx + subl $4,%esi + subl $4,%edi + decl %ebx + jnz L(oop2) + +L(end2): + shll %cl,%edx /* compute least significant limb */ + movl %edx,(%edi) /* store it */ + + popl %eax /* pop carry limb */ + + popl %ebx + popl %ebp + popl %esi + popl %edi + + LEAVE + ret + +/* We loop from least significant end of the arrays, which is only + permissible if the source and destination don't overlap, since the + function is documented to work for overlapping source and destination. +*/ + +L(special): + movl (%esi),%edx + addl $4,%esi + + decl %ebx + pushl %ebx + shrl $3,%ebx + + addl %edx,%edx + incl %ebx + decl %ebx + jz L(Lend) + + movl (%edi),%eax /* fetch destination cache line */ + + ALIGN (2) +L(Loop): + movl 28(%edi),%eax /* fetch destination cache line */ + movl %edx,%ebp + + movl (%esi),%eax + movl 4(%esi),%edx + adcl %eax,%eax + movl %ebp,(%edi) + adcl %edx,%edx + movl %eax,4(%edi) + + movl 8(%esi),%ebp + movl 12(%esi),%eax + adcl %ebp,%ebp + movl %edx,8(%edi) + adcl %eax,%eax + movl %ebp,12(%edi) + + movl 16(%esi),%edx + movl 20(%esi),%ebp + adcl %edx,%edx + movl %eax,16(%edi) + adcl %ebp,%ebp + movl %edx,20(%edi) + + movl 24(%esi),%eax + movl 28(%esi),%edx + adcl %eax,%eax + movl %ebp,24(%edi) + adcl %edx,%edx + movl %eax,28(%edi) + + leal 32(%esi),%esi /* use leal not to clobber carry */ + leal 32(%edi),%edi + decl %ebx + jnz L(Loop) + +L(Lend): + popl %ebx + sbbl %eax,%eax /* save carry in %eax */ + andl $7,%ebx + jz L(Lend2) + addl %eax,%eax /* restore carry from eax */ +L(Loop2): + movl %edx,%ebp + movl (%esi),%edx + adcl %edx,%edx + movl %ebp,(%edi) + + leal 4(%esi),%esi /* use leal not to clobber carry */ + leal 4(%edi),%edi + decl %ebx + jnz L(Loop2) + + jmp L(L1) +L(Lend2): + addl %eax,%eax /* restore carry from eax */ +L(L1): movl %edx,(%edi) /* store last limb */ + + sbbl %eax,%eax + negl %eax + + popl %ebx + popl %ebp + popl %esi + popl %edi + + LEAVE + ret +END (BP_SYM (__mpn_lshift)) diff --git a/src/kernel/libroot/posix/glibc/arch/x86/mul_1.S b/src/kernel/libroot/posix/glibc/arch/x86/mul_1.S new file mode 100644 index 0000000000..f7865697e6 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/arch/x86/mul_1.S @@ -0,0 +1,85 @@ +/* Pentium __mpn_mul_1 -- Multiply a limb vector with a limb and store + the result in a second limb vector. + Copyright (C) 1992, 94, 96, 97, 98, 00 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, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" +#include "bp-sym.h" +#include "bp-asm.h" + +#define PARMS LINKAGE+16 /* space for 4 saved regs */ +#define RES PARMS +#define S1 RES+PTR_SIZE +#define SIZE S1+PTR_SIZE +#define S2LIMB SIZE+4 + +#define res_ptr edi +#define s1_ptr esi +#define size ecx +#define s2_limb ebx + + .text +ENTRY (BP_SYM (__mpn_mul_1)) + ENTER + + pushl %edi + pushl %esi + pushl %ebp + pushl %ebx + + movl RES(%esp), %res_ptr + movl S1(%esp), %s1_ptr + movl SIZE(%esp), %size + movl S2LIMB(%esp), %s2_limb +#if __BOUNDED_POINTERS__ + shll $2, %size /* convert limbs to bytes */ + CHECK_BOUNDS_BOTH_WIDE (%res_ptr, RES(%esp), %size) + CHECK_BOUNDS_BOTH_WIDE (%s1_ptr, S1(%esp), %size) + shrl $2, %size +#endif + leal (%res_ptr,%size,4), %res_ptr + leal (%s1_ptr,%size,4), %s1_ptr + negl %size + xorl %ebp, %ebp + ALIGN (3) + +L(oop): adcl $0, %ebp + movl (%s1_ptr,%size,4), %eax + + mull %s2_limb + + addl %eax, %ebp + + movl %ebp, (%res_ptr,%size,4) + incl %size + + movl %edx, %ebp + jnz L(oop) + + adcl $0, %ebp + movl %ebp, %eax + popl %ebx + popl %ebp + popl %esi + popl %edi + + LEAVE + ret +#undef size +END (BP_SYM (__mpn_mul_1)) diff --git a/src/kernel/libroot/posix/glibc/arch/x86/rshift.S b/src/kernel/libroot/posix/glibc/arch/x86/rshift.S new file mode 100644 index 0000000000..db9326a442 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/arch/x86/rshift.S @@ -0,0 +1,232 @@ +/* Pentium optimized __mpn_rshift -- + Copyright (C) 1992, 94, 95, 96, 97, 98, 2000 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, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" +#include "bp-sym.h" +#include "bp-asm.h" + +#define PARMS LINKAGE+16 /* space for 4 saved regs */ +#define RES PARMS +#define S RES+PTR_SIZE +#define SIZE S+PTR_SIZE +#define CNT SIZE+4 + + .text +ENTRY (BP_SYM (__mpn_rshift)) + ENTER + + pushl %edi + pushl %esi + pushl %ebp + pushl %ebx + + movl RES(%esp),%edi + movl S(%esp),%esi + movl SIZE(%esp),%ebx + movl CNT(%esp),%ecx +#if __BOUNDED_POINTERS__ + shll $2, %ebx /* convert limbs to bytes */ + CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ebx) + CHECK_BOUNDS_BOTH_WIDE (%esi, S(%esp), %ebx) + shrl $2, %ebx +#endif + +/* We can use faster code for shift-by-1 under certain conditions. */ + cmp $1,%ecx + jne L(normal) + leal 4(%edi),%eax + cmpl %esi,%eax + jnc L(special) /* jump if res_ptr + 1 >= s_ptr */ + leal (%edi,%ebx,4),%eax + cmpl %eax,%esi + jnc L(special) /* jump if s_ptr >= res_ptr + size */ + +L(normal): + movl (%esi),%edx + addl $4,%esi + xorl %eax,%eax + shrdl %cl,%edx,%eax /* compute carry limb */ + pushl %eax /* push carry limb onto stack */ + + decl %ebx + pushl %ebx + shrl $3,%ebx + jz L(end) + + movl (%edi),%eax /* fetch destination cache line */ + + ALIGN (2) +L(oop): movl 28(%edi),%eax /* fetch destination cache line */ + movl %edx,%ebp + + movl (%esi),%eax + movl 4(%esi),%edx + shrdl %cl,%eax,%ebp + shrdl %cl,%edx,%eax + movl %ebp,(%edi) + movl %eax,4(%edi) + + movl 8(%esi),%ebp + movl 12(%esi),%eax + shrdl %cl,%ebp,%edx + shrdl %cl,%eax,%ebp + movl %edx,8(%edi) + movl %ebp,12(%edi) + + movl 16(%esi),%edx + movl 20(%esi),%ebp + shrdl %cl,%edx,%eax + shrdl %cl,%ebp,%edx + movl %eax,16(%edi) + movl %edx,20(%edi) + + movl 24(%esi),%eax + movl 28(%esi),%edx + shrdl %cl,%eax,%ebp + shrdl %cl,%edx,%eax + movl %ebp,24(%edi) + movl %eax,28(%edi) + + addl $32,%esi + addl $32,%edi + decl %ebx + jnz L(oop) + +L(end): popl %ebx + andl $7,%ebx + jz L(end2) +L(oop2): + movl (%esi),%eax + shrdl %cl,%eax,%edx /* compute result limb */ + movl %edx,(%edi) + movl %eax,%edx + addl $4,%esi + addl $4,%edi + decl %ebx + jnz L(oop2) + +L(end2): + shrl %cl,%edx /* compute most significant limb */ + movl %edx,(%edi) /* store it */ + + popl %eax /* pop carry limb */ + + popl %ebx + popl %ebp + popl %esi + popl %edi + + LEAVE + ret + +/* We loop from least significant end of the arrays, which is only + permissible if the source and destination don't overlap, since the + function is documented to work for overlapping source and destination. +*/ + +L(special): + leal -4(%edi,%ebx,4),%edi + leal -4(%esi,%ebx,4),%esi + + movl (%esi),%edx + subl $4,%esi + + decl %ebx + pushl %ebx + shrl $3,%ebx + + shrl $1,%edx + incl %ebx + decl %ebx + jz L(Lend) + + movl (%edi),%eax /* fetch destination cache line */ + + ALIGN (2) +L(Loop): + movl -28(%edi),%eax /* fetch destination cache line */ + movl %edx,%ebp + + movl (%esi),%eax + movl -4(%esi),%edx + rcrl $1,%eax + movl %ebp,(%edi) + rcrl $1,%edx + movl %eax,-4(%edi) + + movl -8(%esi),%ebp + movl -12(%esi),%eax + rcrl $1,%ebp + movl %edx,-8(%edi) + rcrl $1,%eax + movl %ebp,-12(%edi) + + movl -16(%esi),%edx + movl -20(%esi),%ebp + rcrl $1,%edx + movl %eax,-16(%edi) + rcrl $1,%ebp + movl %edx,-20(%edi) + + movl -24(%esi),%eax + movl -28(%esi),%edx + rcrl $1,%eax + movl %ebp,-24(%edi) + rcrl $1,%edx + movl %eax,-28(%edi) + + leal -32(%esi),%esi /* use leal not to clobber carry */ + leal -32(%edi),%edi + decl %ebx + jnz L(Loop) + +L(Lend): + popl %ebx + sbbl %eax,%eax /* save carry in %eax */ + andl $7,%ebx + jz L(Lend2) + addl %eax,%eax /* restore carry from eax */ +L(Loop2): + movl %edx,%ebp + movl (%esi),%edx + rcrl $1,%edx + movl %ebp,(%edi) + + leal -4(%esi),%esi /* use leal not to clobber carry */ + leal -4(%edi),%edi + decl %ebx + jnz L(Loop2) + + jmp L(L1) +L(Lend2): + addl %eax,%eax /* restore carry from eax */ +L(L1): movl %edx,(%edi) /* store last limb */ + + movl $0,%eax + rcrl $1,%eax + + popl %ebx + popl %ebp + popl %esi + popl %edi + + LEAVE + ret +END (BP_SYM (__mpn_rshift)) diff --git a/src/kernel/libroot/posix/glibc/arch/x86/sub_n.S b/src/kernel/libroot/posix/glibc/arch/x86/sub_n.S new file mode 100644 index 0000000000..fcc9cba4ad --- /dev/null +++ b/src/kernel/libroot/posix/glibc/arch/x86/sub_n.S @@ -0,0 +1,137 @@ +/* Pentium __mpn_sub_n -- Subtract two limb vectors of the same length > 0 + and store difference in a third limb vector. + Copyright (C) 1992, 94, 95, 96, 97, 98, 2000 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, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" +#include "bp-sym.h" +#include "bp-asm.h" + +#define PARMS LINKAGE+16 /* space for 4 saved regs */ +#define RES PARMS +#define S1 RES+PTR_SIZE +#define S2 S1+PTR_SIZE +#define SIZE S2+PTR_SIZE + + .text +ENTRY (BP_SYM (__mpn_sub_n)) + ENTER + + pushl %edi + pushl %esi + pushl %ebp + pushl %ebx + + movl RES(%esp),%edi + movl S1(%esp),%esi + movl S2(%esp),%ebx + movl SIZE(%esp),%ecx +#if __BOUNDED_POINTERS__ + shll $2, %ecx /* convert limbs to bytes */ + CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ecx) + CHECK_BOUNDS_BOTH_WIDE (%esi, S1(%esp), %ecx) + CHECK_BOUNDS_BOTH_WIDE (%ebx, S2(%esp), %ecx) + shrl $2, %ecx +#endif + movl (%ebx),%ebp + + decl %ecx + movl %ecx,%edx + shrl $3,%ecx + andl $7,%edx + testl %ecx,%ecx /* zero carry flag */ + jz L(end) + pushl %edx + + ALIGN (3) +L(oop): movl 28(%edi),%eax /* fetch destination cache line */ + leal 32(%edi),%edi + +L(1): movl (%esi),%eax + movl 4(%esi),%edx + sbbl %ebp,%eax + movl 4(%ebx),%ebp + sbbl %ebp,%edx + movl 8(%ebx),%ebp + movl %eax,-32(%edi) + movl %edx,-28(%edi) + +L(2): movl 8(%esi),%eax + movl 12(%esi),%edx + sbbl %ebp,%eax + movl 12(%ebx),%ebp + sbbl %ebp,%edx + movl 16(%ebx),%ebp + movl %eax,-24(%edi) + movl %edx,-20(%edi) + +L(3): movl 16(%esi),%eax + movl 20(%esi),%edx + sbbl %ebp,%eax + movl 20(%ebx),%ebp + sbbl %ebp,%edx + movl 24(%ebx),%ebp + movl %eax,-16(%edi) + movl %edx,-12(%edi) + +L(4): movl 24(%esi),%eax + movl 28(%esi),%edx + sbbl %ebp,%eax + movl 28(%ebx),%ebp + sbbl %ebp,%edx + movl 32(%ebx),%ebp + movl %eax,-8(%edi) + movl %edx,-4(%edi) + + leal 32(%esi),%esi + leal 32(%ebx),%ebx + decl %ecx + jnz L(oop) + + popl %edx +L(end): + decl %edx /* test %edx w/o clobbering carry */ + js L(end2) + incl %edx +L(oop2): + leal 4(%edi),%edi + movl (%esi),%eax + sbbl %ebp,%eax + movl 4(%ebx),%ebp + movl %eax,-4(%edi) + leal 4(%esi),%esi + leal 4(%ebx),%ebx + decl %edx + jnz L(oop2) +L(end2): + movl (%esi),%eax + sbbl %ebp,%eax + movl %eax,(%edi) + + sbbl %eax,%eax + negl %eax + + popl %ebx + popl %ebp + popl %esi + popl %edi + + LEAVE + ret +END (BP_SYM (__mpn_sub_n)) diff --git a/src/kernel/libroot/posix/glibc/arch/x86/submul_1.S b/src/kernel/libroot/posix/glibc/arch/x86/submul_1.S new file mode 100644 index 0000000000..542200110f --- /dev/null +++ b/src/kernel/libroot/posix/glibc/arch/x86/submul_1.S @@ -0,0 +1,89 @@ +/* Pentium __mpn_submul_1 -- Multiply a limb vector with a limb and subtract + the result from a second limb vector. + Copyright (C) 1992, 94, 96, 97, 98, 00 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, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" +#include "bp-sym.h" +#include "bp-asm.h" + +#define PARMS LINKAGE+16 /* space for 4 saved regs */ +#define RES PARMS +#define S1 RES+PTR_SIZE +#define SIZE S1+PTR_SIZE +#define S2LIMB SIZE+4 + +#define res_ptr edi +#define s1_ptr esi +#define size ecx +#define s2_limb ebx + + .text +ENTRY (BP_SYM (__mpn_submul_1)) + ENTER + + pushl %edi + pushl %esi + pushl %ebp + pushl %ebx + + movl RES(%esp), %res_ptr + movl S1(%esp), %s1_ptr + movl SIZE(%esp), %size + movl S2LIMB(%esp), %s2_limb +#if __BOUNDED_POINTERS__ + shll $2, %sizeP /* convert limbs to bytes */ + CHECK_BOUNDS_BOTH_WIDE (%res_ptr, RES(%esp), %sizeP) + CHECK_BOUNDS_BOTH_WIDE (%s1_ptr, S1(%esp), %sizeP) + shrl $2, %sizeP +#endif + leal (%res_ptr,%size,4), %res_ptr + leal (%s1_ptr,%size,4), %s1_ptr + negl %size + xorl %ebp, %ebp + ALIGN (3) + +L(oop): adcl $0, %ebp + movl (%s1_ptr,%size,4), %eax + + mull %s2_limb + + addl %ebp, %eax + movl (%res_ptr,%size,4), %ebp + + adcl $0, %edx + subl %eax, %ebp + + movl %ebp, (%res_ptr,%size,4) + incl %size + + movl %edx, %ebp + jnz L(oop) + + adcl $0, %ebp + movl %ebp, %eax + popl %ebx + popl %ebp + popl %esi + popl %edi + + LEAVE + ret +#undef size +END (BP_SYM (__mpn_submul_1))