2.9
[glibc/nacl-glibc.git] / sysdeps / powerpc / powerpc32 / lshift.S
blob65054f229de50ae549e01ea3099695720ef65927
1 /* Shift a limb left, low level routine.
2    Copyright (C) 1996, 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
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    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
18    02110-1301 USA.  */
20 #include <sysdep.h>
21 #include <bp-sym.h>
22 #include <bp-asm.h>
24 /* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
25                          unsigned int cnt)  */
27 EALIGN (BP_SYM (__mpn_lshift), 3, 0)
29 #if __BOUNDED_POINTERS__
30         slwi r10,r5,2           /* convert limbs to bytes */
31         CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
32         CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
33 #endif
34         mtctr   r5              # copy size into CTR
35         cmplwi  cr0,r5,16       # is size < 16
36         slwi    r0,r5,2
37         add     r7,r3,r0        # make r7 point at end of res
38         add     r4,r4,r0        # make r4 point at end of s1
39         lwzu    r11,-4(r4)      # load first s1 limb
40         subfic  r8,r6,32
41         srw     r3,r11,r8       # compute function return value
42         bge     cr0,L(big)      # branch if size >= 16
44         bdz     L(end1)
46 L(0):   lwzu    r10,-4(r4)
47         slw     r9,r11,r6
48         srw     r12,r10,r8
49         or      r9,r9,r12
50         stwu    r9,-4(r7)
51         bdz     L(end2)
52         lwzu    r11,-4(r4)
53         slw     r9,r10,r6
54         srw     r12,r11,r8
55         or      r9,r9,r12
56         stwu    r9,-4(r7)
57         bdnz    L(0)
59 L(end1):slw     r0,r11,r6
60         stw     r0,-4(r7)
61         blr
64 /* Guaranteed not to succeed.  */
65 L(boom): tweq    r0,r0
67 /* We imitate a case statement, by using (yuk!) fixed-length code chunks,
68    of size 4*12 bytes.  We have to do this (or something) to make this PIC.  */
69 L(big): mflr    r9
70         cfi_register(lr,r9)
71         bltl-   cr0,L(boom)     # Never taken, only used to set LR.
72         slwi    r10,r6,4
73         mflr    r12
74         add     r10,r12,r10
75         slwi    r8,r6,5
76         add     r10,r8,r10
77         mtctr   r10
78         addi    r5,r5,-1
79         mtlr    r9
80         cfi_same_value (lr)
81         bctr
83 L(end2):slw     r0,r10,r6
84         stw     r0,-4(r7)
85         blr
87 #define DO_LSHIFT(n) \
88         mtctr   r5;                                                     \
89 L(n):   lwzu    r10,-4(r4);                                             \
90         slwi    r9,r11,n;                                               \
91         inslwi  r9,r10,n,32-n;                                  \
92         stwu    r9,-4(r7);                                              \
93         bdz-    L(end2);                                                \
94         lwzu    r11,-4(r4);                                             \
95         slwi    r9,r10,n;                                               \
96         inslwi  r9,r11,n,32-n;                                  \
97         stwu    r9,-4(r7);                                              \
98         bdnz    L(n);                                                   \
99         b       L(end1)
101         DO_LSHIFT(1)
102         DO_LSHIFT(2)
103         DO_LSHIFT(3)
104         DO_LSHIFT(4)
105         DO_LSHIFT(5)
106         DO_LSHIFT(6)
107         DO_LSHIFT(7)
108         DO_LSHIFT(8)
109         DO_LSHIFT(9)
110         DO_LSHIFT(10)
111         DO_LSHIFT(11)
112         DO_LSHIFT(12)
113         DO_LSHIFT(13)
114         DO_LSHIFT(14)
115         DO_LSHIFT(15)
116         DO_LSHIFT(16)
117         DO_LSHIFT(17)
118         DO_LSHIFT(18)
119         DO_LSHIFT(19)
120         DO_LSHIFT(20)
121         DO_LSHIFT(21)
122         DO_LSHIFT(22)
123         DO_LSHIFT(23)
124         DO_LSHIFT(24)
125         DO_LSHIFT(25)
126         DO_LSHIFT(26)
127         DO_LSHIFT(27)
128         DO_LSHIFT(28)
129         DO_LSHIFT(29)
130         DO_LSHIFT(30)
131         DO_LSHIFT(31)
133 END (BP_SYM (__mpn_lshift))