Update.
[platform/upstream/glibc.git] / sysdeps / powerpc / add_n.s
1  # Add two limb vectors of equal, non-zero length for PowerPC.
2  # Copyright (C) 1997 Free Software Foundation, Inc.
3  # This file is part of the GNU C Library.
4  #
5  # The GNU C Library is free software; you can redistribute it and/or
6  # modify it under the terms of the GNU Library General Public License as
7  # published by the Free Software Foundation; either version 2 of the
8  # License, or (at your option) any later version.
9  #
10  # The GNU C Library is distributed in the hope that it will be useful,
11  # but WITHOUT ANY WARRANTY; without even the implied warranty of
12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  # Library General Public License for more details.
14  #
15  # You should have received a copy of the GNU Library General Public
16  # License along with the GNU C Library; see the file COPYING.LIB.  If not,
17  # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  # Boston, MA 02111-1307, USA.
19
20  # mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
21  #                      mp_size_t size)
22  # Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1.
23
24  # Note on optimisation: This code is optimal for the 601.  Almost every other
25  # possible 2-unrolled inner loop will not be.  Also, watch out for the
26  # alignment...
27
28         .align 3
29         .globl __mpn_add_n
30         .type    __mpn_add_n,@function
31 __mpn_add_n:
32  # Set up for loop below.
33         mtcrf 0x01,%r6
34         srwi. %r7,%r6,1
35         li    %r10,0
36         mtctr %r7
37         bt    31,2f
38
39  # Clear the carry.
40         addic %r0,%r0,0
41  # Adjust pointers for loop.
42         addi  %r3,%r3,-4
43         addi  %r4,%r4,-4
44         addi  %r5,%r5,-4
45         b     0f
46
47 2:      lwz  %r7,0(%r5)
48         lwz  %r6,0(%r4)
49         addc %r6,%r6,%r7
50         stw  %r6,0(%r3)
51         beq  1f
52
53  # The loop.
54
55  # Align start of loop to an odd word boundary to guarantee that the
56  # last two words can be fetched in one access (for 601).
57 0:      lwz  %r9,4(%r4)
58         lwz  %r8,4(%r5)
59         lwzu %r6,8(%r4)
60         lwzu %r7,8(%r5)
61         adde %r8,%r9,%r8
62         stw  %r8,4(%r3)
63         adde %r6,%r6,%r7
64         stwu %r6,8(%r3)
65         bdnz 0b
66  # return the carry
67 1:      addze %r3,%r10
68         blr