]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/powerpc/powerpc32/lshift.S
2.5-18.1
[thirdparty/glibc.git] / sysdeps / powerpc / powerpc32 / lshift.S
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.
4
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.
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 Lesser General Public License for more details.
14
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. */
19
20 #include <sysdep.h>
21 #include <bp-sym.h>
22 #include <bp-asm.h>
23
24 /* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
25 unsigned int cnt) */
26
27 EALIGN (BP_SYM (__mpn_lshift), 3, 0)
28
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
43
44 bdz L(end1)
45
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)
58
59 L(end1):slw r0,r11,r6
60 stw r0,-4(r7)
61 blr
62
63
64 /* Guaranteed not to succeed. */
65 L(boom): tweq r0,r0
66
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
82
83 L(end2):slw r0,r10,r6
84 stw r0,-4(r7)
85 blr
86
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)
100
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)
132
133 END (BP_SYM (__mpn_lshift))