The first libgcrypt only release.
[libgcrypt.git] / mpi / powerpc32 / mpih-lshift.S
1 /* PowerPC-32 lshift
2  *
3  *      Copyright (C) 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  * _gcry_mpih_lshift( mpi_ptr_t wp,     (r3)
31  *                 mpi_ptr_t up,        (r4)
32  *                 mpi_size_t usize,    (r5)
33  *                 unsigned cnt)        (r6)
34  */
35
36         .toc
37 .csect  .text[PR]
38         .align  2
39         .globl  _gcry_mpih_lshift
40         .globl  ._gcry_mpih_lshift
41         .csect  _gcry_mpih_lshift[DS]
42 _gcry_mpih_lshift:
43         .long   ._gcry_mpih_lshift,  TOC[tc0],    0
44         .csect  .text[PR]
45 ._gcry_mpih_lshift:
46         mtctr   5               # copy size into CTR
47         slwi    0,5,2
48         add     7,3,0           # make r7 point at end of res
49         add     4,4,0           # make r4 point at end of s1
50         subfic  8,6,32
51         lwzu    11,-4(4)        # load first s1 limb
52         srw     3,11,8          # compute function return value
53         bdz     Lend1
54
55 Loop:   lwzu    10,-4(4)
56         slw     9,11,6
57         srw     12,10,8
58         or      9,9,12
59         stwu    9,-4(7)
60         bdz     Lend2
61         lwzu    11,-4(4)
62         slw     9,10,6
63         srw     12,11,8
64         or      9,9,12
65         stwu    9,-4(7)
66         bdnz    Loop
67
68 Lend1:  slw     0,11,6
69         stw     0,-4(7)
70         blr
71
72 Lend2:  slw     0,10,6
73         stw     0,-4(7)
74         blr
75
76 #else
77 /* Shift a limb left, low level routine.
78    Copyright (C) 1996, 1997 Free Software Foundation, Inc.
79    This file is part of the GNU C Library.
80
81    The GNU C Library is free software; you can redistribute it and/or
82    modify it under the terms of the GNU Library General Public License as
83    published by the Free Software Foundation; either version 2 of the
84    License, or (at your option) any later version.
85
86    The GNU C Library is distributed in the hope that it will be useful,
87    but WITHOUT ANY WARRANTY; without even the implied warranty of
88    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
89    Library General Public License for more details.
90
91    You should have received a copy of the GNU Library General Public
92    License along with the GNU C Library; see the file COPYING.LIB.  If not,
93    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
94    Boston, MA 02111-1307, USA.  */
95
96 /* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
97                         unsigned int cnt)  */
98
99 EALIGN(_gcry_mpih_lshift,3,0)
100        mtctr   %r5             # copy size into CTR
101        cmplwi  %cr0,%r5,16     # is size < 16
102        slwi    %r0,%r5,2
103        add     %r7,%r3,%r0     # make r7 point at end of res
104        add     %r4,%r4,%r0     # make r4 point at end of s1
105        lwzu    %r11,-4(%r4)    # load first s1 limb
106        subfic  %r8,%r6,32
107        srw     %r3,%r11,%r8    # compute function return value
108        bge     %cr0,L(big)     # branch if size >= 16
109
110        bdz     L(end1)
111
112 0:     lwzu    %r10,-4(%r4)
113        slw     %r9,%r11,%r6
114        srw     %r12,%r10,%r8
115        or      %r9,%r9,%r12
116        stwu    %r9,-4(%r7)
117        bdz     L(end2)
118        lwzu    %r11,-4(%r4)
119        slw     %r9,%r10,%r6
120        srw     %r12,%r11,%r8
121        or      %r9,%r9,%r12
122        stwu    %r9,-4(%r7)
123        bdnz    0b
124
125 L(end1):slw    %r0,%r11,%r6
126        stw     %r0,-4(%r7)
127        blr
128
129
130 /* Guaranteed not to succeed.  */
131 L(boom): tweq    %r0,%r0
132
133 /* We imitate a case statement, by using (yuk!) fixed-length code chunks,
134    of size 4*12 bytes.  We have to do this (or something) to make this PIC.  */
135 L(big):        mflr    %r9
136        bltl-   %cr0,L(boom)    # Never taken, only used to set LR.
137        slwi    %r10,%r6,4
138        mflr    %r12
139        add     %r10,%r12,%r10
140        slwi    %r8,%r6,5
141        add     %r10,%r8,%r10
142        mtctr   %r10
143        addi    %r5,%r5,-1
144        mtlr    %r9
145        bctr
146
147 L(end2):slw    %r0,%r10,%r6
148        stw     %r0,-4(%r7)
149        blr
150
151 #define DO_LSHIFT(n) \
152        mtctr   %r5;                                                    \
153 0:     lwzu    %r10,-4(%r4);                                           \
154        slwi    %r9,%r11,n;                                             \
155        inslwi  %r9,%r10,n,32-n;                                        \
156        stwu    %r9,-4(%r7);                                            \
157        bdz-    L(end2);                                                \
158        lwzu    %r11,-4(%r4);                                           \
159        slwi    %r9,%r10,n;                                             \
160        inslwi  %r9,%r11,n,32-n;                                        \
161        stwu    %r9,-4(%r7);                                            \
162        bdnz    0b;                                                     \
163        b       L(end1)
164
165        DO_LSHIFT(1)
166        DO_LSHIFT(2)
167        DO_LSHIFT(3)
168        DO_LSHIFT(4)
169        DO_LSHIFT(5)
170        DO_LSHIFT(6)
171        DO_LSHIFT(7)
172        DO_LSHIFT(8)
173        DO_LSHIFT(9)
174        DO_LSHIFT(10)
175        DO_LSHIFT(11)
176        DO_LSHIFT(12)
177        DO_LSHIFT(13)
178        DO_LSHIFT(14)
179        DO_LSHIFT(15)
180        DO_LSHIFT(16)
181        DO_LSHIFT(17)
182        DO_LSHIFT(18)
183        DO_LSHIFT(19)
184        DO_LSHIFT(20)
185        DO_LSHIFT(21)
186        DO_LSHIFT(22)
187        DO_LSHIFT(23)
188        DO_LSHIFT(24)
189        DO_LSHIFT(25)
190        DO_LSHIFT(26)
191        DO_LSHIFT(27)
192        DO_LSHIFT(28)
193        DO_LSHIFT(29)
194        DO_LSHIFT(30)
195        DO_LSHIFT(31)
196
197 END(_gcry_mpih_lshift)
198 #endif