bbc513154d0fc40d04d198558e76db476a7b4211
[libgcrypt.git] / mpi / powerpc32 / mpih-add1.S
1 /* PowerPC-32 add_n -- Add two limb vectors of equal, non-zero length.
2  *
3  * Copyright (C) 1992, 1994, 1995, 1998 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include "sysdep.h"
23 #include "asm-syntax.h"
24
25
26 #ifndef USE_PPC_PATCHES
27
28 /*******************
29  *  mpi_limb_t
30  *  mpihelp_add_n( mpi_ptr_t res_ptr,   (r3)
31  *                 mpi_ptr_t s1_ptr,    (r4)
32  *                 mpi_ptr_t s2_ptr,    (r5)
33  *                 mpi_size_t size)     (r6)
34  */
35
36         .toc
37         .extern mpihelp_add_n[DS]
38         .extern .mpihelp_add_n
39 .csect [PR]
40         .align 2
41         .globl mpihelp_add_n
42         .globl .mpihelp_add_n
43         .csect mpihelp_add_n[DS]
44 mpihelp_add_n:
45         .long .mpihelp_add_n, TOC[tc0], 0
46         .csect [PR]
47 .mpihelp_add_n:
48         mtctr   6               # copy size into CTR
49         lwz     8,0(4)          # load least significant s1 limb
50         lwz     0,0(5)          # load least significant s2 limb
51         addi    3,3,-4          # offset res_ptr, it's updated before used
52         addc    7,0,8           # add least significant limbs, set cy
53         bdz     Lend            # If done, skip loop
54 Loop:   lwzu    8,4(4)          # load s1 limb and update s1_ptr
55         lwzu    0,4(5)          # load s2 limb and update s2_ptr
56         stwu    7,4(3)          # store previous limb in load latency slot
57         adde    7,0,8           # add new limbs with cy, set cy
58         bdnz    Loop            # decrement CTR and loop back
59 Lend:   stw     7,4(3)          # store ultimate result limb
60         li      3,0             # load cy into ...
61         addze   3,3             # ... return value register
62         blr
63
64 #else
65 /* Add two limb vectors of equal, non-zero length for PowerPC.
66    Copyright (C) 1997 Free Software Foundation, Inc.
67    This file is part of the GNU C Library.
68
69    The GNU C Library is free software; you can redistribute it and/or
70    modify it under the terms of the GNU Library General Public License as
71    published by the Free Software Foundation; either version 2 of the
72    License, or (at your option) any later version.
73
74    The GNU C Library is distributed in the hope that it will be useful,
75    but WITHOUT ANY WARRANTY; without even the implied warranty of
76    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
77    Library General Public License for more details.
78
79    You should have received a copy of the GNU Library General Public
80    License along with the GNU C Library; see the file COPYING.LIB.  If not,
81    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
82    Boston, MA 02111-1307, USA.  */
83
84 #include "sysdep.h"
85 #include "asm-syntax.h"
86
87
88 /* mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
89                         mp_size_t size)
90    Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1.  */
91
92 /* Note on optimisation: This code is optimal for the 601.  Almost every other
93    possible 2-unrolled inner loop will not be.  Also, watch out for the
94    alignment...  */
95
96 EALIGN(_mpihelp_add_n,3,0)
97 /* Set up for loop below.  */
98        mtcrf 0x01,%r6
99        srwi. %r7,%r6,1
100        li    %r10,0
101        mtctr %r7
102        bt    31,2f
103
104 /* Clear the carry.  */
105        addic %r0,%r0,0
106 /* Adjust pointers for loop.  */
107        addi  %r3,%r3,-4
108        addi  %r4,%r4,-4
109        addi  %r5,%r5,-4
110        b     0f
111
112 2:     lwz  %r7,0(%r5)
113        lwz  %r6,0(%r4)
114        addc %r6,%r6,%r7
115        stw  %r6,0(%r3)
116         beq  1f
117
118 /* The loop.  */
119
120 /* Align start of loop to an odd word boundary to guarantee that the
121    last two words can be fetched in one access (for 601).  */
122 0:     lwz  %r9,4(%r4)
123        lwz  %r8,4(%r5)
124        lwzu %r6,8(%r4)
125        lwzu %r7,8(%r5)
126        adde %r8,%r9,%r8
127        stw  %r8,4(%r3)
128        adde %r6,%r6,%r7
129        stwu %r6,8(%r3)
130        bdnz 0b
131 /* Return the carry.  */
132 1:     addze %r3,%r10
133        blr
134 END(_mpihelp_add_n)
135 #endif
136