added a ppc arch directory for GLibC (based on 2.2.5), untested

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11644 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2005-03-10 19:00:09 +00:00
parent c862c0e4a4
commit 864ce0e4d7
10 changed files with 774 additions and 0 deletions

View File

@ -0,0 +1,10 @@
SubDir OBOS_TOP src kernel libroot posix arch x86 ;
KernelMergeObject posix_arch_$(OBOS_ARCH).o :
setjmp.c
setjmp_save_sigs.c
sigsetjmp.S
siglongjmp.S
: -fPIC -DPIC
;

View File

@ -0,0 +1,77 @@
/* Add two limb vectors of equal, non-zero length for PowerPC.
Copyright (C) 1997, 1999, 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 <bp-sym.h>
#include <bp-asm.h>
/* mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
mp_size_t size)
Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1. */
/* Note on optimisation: This code is optimal for the 601. Almost every other
possible 2-unrolled inner loop will not be. Also, watch out for the
alignment... */
EALIGN (BP_SYM (__mpn_add_n), 3, 0)
#if __BOUNDED_POINTERS__
slwi r10,r6,2 /* convert limbs to bytes */
CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
CHECK_BOUNDS_BOTH_WIDE (r5, r8, r9, r10)
#endif
/* Set up for loop below. */
mtcrf 0x01,r6
srwi. r7,r6,1
li r10,0
mtctr r7
bt 31,L(2)
/* Clear the carry. */
addic r0,r0,0
/* Adjust pointers for loop. */
addi r3,r3,-4
addi r4,r4,-4
addi r5,r5,-4
b L(0)
L(2): lwz r7,0(r5)
lwz r6,0(r4)
addc r6,r6,r7
stw r6,0(r3)
beq L(1)
/* The loop. */
/* Align start of loop to an odd word boundary to guarantee that the
last two words can be fetched in one access (for 601). */
L(0): lwz r9,4(r4)
lwz r8,4(r5)
lwzu r6,8(r4)
lwzu r7,8(r5)
adde r8,r9,r8
stw r8,4(r3)
adde r6,r6,r7
stwu r6,8(r3)
bdnz L(0)
/* Return the carry. */
L(1): addze r3,r10
blr
END (BP_SYM (__mpn_add_n))

View File

@ -0,0 +1,56 @@
/* Multiply a limb vector by a single limb, for PowerPC.
Copyright (C) 1993-1995, 1997, 1999, 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 <bp-sym.h>
#include <bp-asm.h>
/* mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
mp_size_t s1_size, mp_limb_t s2_limb)
Calculate res+s1*s2 and put result back in res; return carry. */
ENTRY (BP_SYM (__mpn_addmul_1))
#if __BOUNDED_POINTERS__
slwi r10,r5,2 /* convert limbs to bytes */
CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
#endif
mtctr r5
lwz r0,0(r4)
mullw r7,r0,r6
mulhwu r10,r0,r6
lwz r9,0(r3)
addc r8,r7,r9
addi r3,r3,-4 /* adjust res_ptr */
bdz L(1)
L(0): lwzu r0,4(r4)
stwu r8,4(r3)
mullw r8,r0,r6
adde r7,r8,r10
mulhwu r10,r0,r6
lwz r9,4(r3)
addze r10,r10
addc r8,r7,r9
bdnz L(0)
L(1): stw r8,4(r3)
addze r3,r10
blr
END (BP_SYM (__mpn_addmul_1))

View File

@ -0,0 +1,95 @@
/* Copyright (C) 1995, 1996, 1997, 1998 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 <float.h>
#include <math.h>
#include <stdlib.h>
/* 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;
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
{
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;
}
}
}
return N;
}

View File

@ -0,0 +1,131 @@
/* Shift a limb left, low level routine.
Copyright (C) 1996, 1997, 1999, 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 <bp-sym.h>
#include <bp-asm.h>
/* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
unsigned int cnt) */
EALIGN (BP_SYM (__mpn_lshift), 3, 0)
#if __BOUNDED_POINTERS__
slwi r10,r5,2 /* convert limbs to bytes */
CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
#endif
mtctr r5 # copy size into CTR
cmplwi cr0,r5,16 # is size < 16
slwi r0,r5,2
add r7,r3,r0 # make r7 point at end of res
add r4,r4,r0 # make r4 point at end of s1
lwzu r11,-4(r4) # load first s1 limb
subfic r8,r6,32
srw r3,r11,r8 # compute function return value
bge cr0,L(big) # branch if size >= 16
bdz L(end1)
L(0): lwzu r10,-4(r4)
slw r9,r11,r6
srw r12,r10,r8
or r9,r9,r12
stwu r9,-4(r7)
bdz L(end2)
lwzu r11,-4(r4)
slw r9,r10,r6
srw r12,r11,r8
or r9,r9,r12
stwu r9,-4(r7)
bdnz L(0)
L(end1):slw r0,r11,r6
stw r0,-4(r7)
blr
/* Guaranteed not to succeed. */
L(boom): tweq r0,r0
/* We imitate a case statement, by using (yuk!) fixed-length code chunks,
of size 4*12 bytes. We have to do this (or something) to make this PIC. */
L(big): mflr r9
bltl- cr0,L(boom) # Never taken, only used to set LR.
slwi r10,r6,4
mflr r12
add r10,r12,r10
slwi r8,r6,5
add r10,r8,r10
mtctr r10
addi r5,r5,-1
mtlr r9
bctr
L(end2):slw r0,r10,r6
stw r0,-4(r7)
blr
#define DO_LSHIFT(n) \
mtctr r5; \
L(n): lwzu r10,-4(r4); \
slwi r9,r11,n; \
inslwi r9,r10,n,32-n; \
stwu r9,-4(r7); \
bdz- L(end2); \
lwzu r11,-4(r4); \
slwi r9,r10,n; \
inslwi r9,r11,n,32-n; \
stwu r9,-4(r7); \
bdnz L(n); \
b L(end1)
DO_LSHIFT(1)
DO_LSHIFT(2)
DO_LSHIFT(3)
DO_LSHIFT(4)
DO_LSHIFT(5)
DO_LSHIFT(6)
DO_LSHIFT(7)
DO_LSHIFT(8)
DO_LSHIFT(9)
DO_LSHIFT(10)
DO_LSHIFT(11)
DO_LSHIFT(12)
DO_LSHIFT(13)
DO_LSHIFT(14)
DO_LSHIFT(15)
DO_LSHIFT(16)
DO_LSHIFT(17)
DO_LSHIFT(18)
DO_LSHIFT(19)
DO_LSHIFT(20)
DO_LSHIFT(21)
DO_LSHIFT(22)
DO_LSHIFT(23)
DO_LSHIFT(24)
DO_LSHIFT(25)
DO_LSHIFT(26)
DO_LSHIFT(27)
DO_LSHIFT(28)
DO_LSHIFT(29)
DO_LSHIFT(30)
DO_LSHIFT(31)
END (BP_SYM (__mpn_lshift))

View File

@ -0,0 +1,152 @@
/* mpn_mul -- Multiply two natural numbers.
Copyright (C) 1991, 1993, 1994, 1996 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 "gmp.h"
#include "gmp-impl.h"
/* Multiply the natural numbers u (pointed to by UP, with USIZE limbs)
and v (pointed to by VP, with VSIZE limbs), and store the result at
PRODP. USIZE + VSIZE limbs are always stored, but if the input
operands are normalized. Return the most significant limb of the
result.
NOTE: The space pointed to by PRODP is overwritten before finished
with U and V, so overlap is an error.
Argument constraints:
1. USIZE >= VSIZE.
2. PRODP != UP and PRODP != VP, i.e. the destination
must be distinct from the multiplier and the multiplicand. */
/* If KARATSUBA_THRESHOLD is not already defined, define it to a
value which is good on most machines. */
#ifndef KARATSUBA_THRESHOLD
#define KARATSUBA_THRESHOLD 32
#endif
mp_limb_t
#if __STDC__
mpn_mul (mp_ptr prodp,
mp_srcptr up, mp_size_t usize,
mp_srcptr vp, mp_size_t vsize)
#else
mpn_mul (prodp, up, usize, vp, vsize)
mp_ptr prodp;
mp_srcptr up;
mp_size_t usize;
mp_srcptr vp;
mp_size_t vsize;
#endif
{
mp_ptr prod_endp = prodp + usize + vsize - 1;
mp_limb_t cy;
mp_ptr tspace;
TMP_DECL (marker);
if (vsize < KARATSUBA_THRESHOLD)
{
/* Handle simple cases with traditional multiplication.
This is the most critical code of the entire function. All
multiplies rely on this, both small and huge. Small ones arrive
here immediately. Huge ones arrive here as this is the base case
for Karatsuba's recursive algorithm below. */
mp_size_t i;
mp_limb_t cy_limb;
mp_limb_t v_limb;
if (vsize == 0)
return 0;
/* Multiply by the first limb in V separately, as the result can be
stored (not added) to PROD. We also avoid a loop for zeroing. */
v_limb = vp[0];
if (v_limb <= 1)
{
if (v_limb == 1)
MPN_COPY (prodp, up, usize);
else
MPN_ZERO (prodp, usize);
cy_limb = 0;
}
else
cy_limb = mpn_mul_1 (prodp, up, usize, v_limb);
prodp[usize] = cy_limb;
prodp++;
/* For each iteration in the outer loop, multiply one limb from
U with one limb from V, and add it to PROD. */
for (i = 1; i < vsize; i++)
{
v_limb = vp[i];
if (v_limb <= 1)
{
cy_limb = 0;
if (v_limb == 1)
cy_limb = mpn_add_n (prodp, prodp, up, usize);
}
else
cy_limb = mpn_addmul_1 (prodp, up, usize, v_limb);
prodp[usize] = cy_limb;
prodp++;
}
return cy_limb;
}
TMP_MARK (marker);
tspace = (mp_ptr) TMP_ALLOC (2 * vsize * BYTES_PER_MP_LIMB);
MPN_MUL_N_RECURSE (prodp, up, vp, vsize, tspace);
prodp += vsize;
up += vsize;
usize -= vsize;
if (usize >= vsize)
{
mp_ptr tp = (mp_ptr) TMP_ALLOC (2 * vsize * BYTES_PER_MP_LIMB);
do
{
MPN_MUL_N_RECURSE (tp, up, vp, vsize, tspace);
cy = mpn_add_n (prodp, prodp, tp, vsize);
mpn_add_1 (prodp + vsize, tp + vsize, vsize, cy);
prodp += vsize;
up += vsize;
usize -= vsize;
}
while (usize >= vsize);
}
/* True: usize < vsize. */
/* Make life simple: Recurse. */
if (usize != 0)
{
mpn_mul (tspace, vp, vsize, up, usize);
cy = mpn_add_n (prodp, prodp, tspace, vsize);
mpn_add_1 (prodp + vsize, tspace + vsize, usize, cy);
}
TMP_FREE (marker);
return *prod_endp;
}

View File

@ -0,0 +1,53 @@
/* Multiply a limb vector by a limb, for PowerPC.
Copyright (C) 1993-1995, 1997, 1999, 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 <bp-sym.h>
#include <bp-asm.h>
/* mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
mp_size_t s1_size, mp_limb_t s2_limb)
Calculate s1*s2 and put result in res_ptr; return carry. */
ENTRY (BP_SYM (__mpn_mul_1))
#if __BOUNDED_POINTERS__
slwi r10,r5,2 /* convert limbs to bytes */
CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
#endif
mtctr r5
lwz r0,0(r4)
mullw r7,r0,r6
mulhwu r10,r0,r6
addi r3,r3,-4 # adjust res_ptr
addic r5,r5,0 # clear cy with dummy insn
bdz L(1)
L(0): lwzu r0,4(r4)
stwu r7,4(r3)
mullw r8,r0,r6
adde r7,r8,r10
mulhwu r10,r0,r6
bdnz L(0)
L(1): stw r7,4(r3)
addze r3,r10
blr
END (BP_SYM (__mpn_mul_1))

View File

@ -0,0 +1,63 @@
/* Shift a limb right, low level routine.
Copyright (C) 1995, 1997, 1999, 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 <bp-sym.h>
#include <bp-asm.h>
/* INPUT PARAMETERS
res_ptr r3
s1_ptr r4
size r5
cnt r6 */
ENTRY (BP_SYM (__mpn_rshift))
#if __BOUNDED_POINTERS__
slwi r10,r5,2 /* convert limbs to bytes */
CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
#endif
mtctr r5 # copy size into CTR
addi r7,r3,-4 # move adjusted res_ptr to free return reg
subfic r8,r6,32
lwz r11,0(r4) # load first s1 limb
slw r3,r11,r8 # compute function return value
bdz L(1)
L(0): lwzu r10,4(r4)
srw r9,r11,r6
slw r12,r10,r8
or r9,r9,r12
stwu r9,4(r7)
bdz L(2)
lwzu r11,4(r4)
srw r9,r10,r6
slw r12,r11,r8
or r9,r9,r12
stwu r9,4(r7)
bdnz L(0)
L(1): srw r0,r11,r6
stw r0,4(r7)
blr
L(2): srw r0,r10,r6
stw r0,4(r7)
blr
END (BP_SYM (__mpn_rshift))

View File

@ -0,0 +1,78 @@
/* Subtract two limb vectors of equal, non-zero length for PowerPC.
Copyright (C) 1997, 1999, 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 <bp-sym.h>
#include <bp-asm.h>
/* mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
mp_size_t size)
Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1. */
/* Note on optimisation: This code is optimal for the 601. Almost every other
possible 2-unrolled inner loop will not be. Also, watch out for the
alignment... */
EALIGN (BP_SYM (__mpn_sub_n), 3, 1)
#if __BOUNDED_POINTERS__
slwi r10,r6,2 /* convert limbs to bytes */
CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
CHECK_BOUNDS_BOTH_WIDE (r5, r8, r9, r10)
#endif
/* Set up for loop below. */
mtcrf 0x01,r6
srwi. r7,r6,1
mtctr r7
bt 31,L(2)
/* Set the carry (clear the borrow). */
subfc r0,r0,r0
/* Adjust pointers for loop. */
addi r3,r3,-4
addi r4,r4,-4
addi r5,r5,-4
b L(0)
L(2): lwz r7,0(r5)
lwz r6,0(r4)
subfc r6,r7,r6
stw r6,0(r3)
beq L(1)
/* Align start of loop to an odd word boundary to guarantee that the
last two words can be fetched in one access (for 601). This turns
out to be important. */
L(0):
lwz r9,4(r4)
lwz r8,4(r5)
lwzu r6,8(r4)
lwzu r7,8(r5)
subfe r8,r8,r9
stw r8,4(r3)
subfe r6,r7,r6
stwu r6,8(r3)
bdnz L(0)
/* Return the borrow. */
L(1): subfe r3,r3,r3
neg r3,r3
blr
END (BP_SYM (__mpn_sub_n))

View File

@ -0,0 +1,59 @@
/* Multiply a limb vector by a single limb, for PowerPC.
Copyright (C) 1993-1995, 1997, 1999, 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 <bp-sym.h>
#include <bp-asm.h>
/* mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
mp_size_t s1_size, mp_limb_t s2_limb)
Calculate res-s1*s2 and put result back in res; return carry. */
ENTRY (BP_SYM (__mpn_submul_1))
#if __BOUNDED_POINTERS__
slwi r10,r5,2 /* convert limbs to bytes */
CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
#endif
mtctr r5
lwz r0,0(r4)
mullw r7,r0,r6
mulhwu r10,r0,r6
lwz r9,0(r3)
subf r8,r7,r9
addc r7,r7,r8 # invert cy (r7 is junk)
addi r3,r3,-4 # adjust res_ptr
bdz L(1)
L(0): lwzu r0,4(r4)
stwu r8,4(r3)
mullw r8,r0,r6
adde r7,r8,r10
mulhwu r10,r0,r6
lwz r9,4(r3)
addze r10,r10
subf r8,r7,r9
addc r7,r7,r8 # invert cy (r7 is junk)
bdnz L(0)
L(1): stw r8,4(r3)
addze r3,r10
blr
END (BP_SYM (__mpn_submul_1))