1/* Shift a limb left, low level routine.
2 Copyright (C) 1996-2024 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, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <sysdep.h>
20
21/* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
22 unsigned int cnt) */
23
24EALIGN (__mpn_lshift, 3, 0)
25
26 mtctr r5 # copy size into CTR
27 cmplwi cr0,r5,16 # is size < 16
28 slwi r0,r5,2
29 add r7,r3,r0 # make r7 point at end of res
30 add r4,r4,r0 # make r4 point at end of s1
31 lwzu r11,-4(r4) # load first s1 limb
32 subfic r8,r6,32
33 srw r3,r11,r8 # compute function return value
34 bge cr0,L(big) # branch if size >= 16
35
36 bdz L(end1)
37
38L(0): lwzu r10,-4(r4)
39 slw r9,r11,r6
40 srw r12,r10,r8
41 or r9,r9,r12
42 stwu r9,-4(r7)
43 bdz L(end2)
44 lwzu r11,-4(r4)
45 slw r9,r10,r6
46 srw r12,r11,r8
47 or r9,r9,r12
48 stwu r9,-4(r7)
49 bdnz L(0)
50
51L(end1):slw r0,r11,r6
52 stw r0,-4(r7)
53 blr
54
55
56/* Guaranteed not to succeed. */
57L(boom): tweq r0,r0
58
59/* We imitate a case statement, by using (yuk!) fixed-length code chunks,
60 of size 4*12 bytes. We have to do this (or something) to make this PIC. */
61L(big): mflr r9
62 cfi_register(lr,r9)
63 bltl- cr0,L(boom) # Never taken, only used to set LR.
64 slwi r10,r6,4
65 mflr r12
66 add r10,r12,r10
67 slwi r8,r6,5
68 add r10,r8,r10
69 mtctr r10
70 addi r5,r5,-1
71 mtlr r9
72 cfi_same_value (lr)
73 bctr
74
75L(end2):slw r0,r10,r6
76 stw r0,-4(r7)
77 blr
78
79#define DO_LSHIFT(n) \
80 mtctr r5; \
81L(n): lwzu r10,-4(r4); \
82 slwi r9,r11,n; \
83 inslwi r9,r10,n,32-n; \
84 stwu r9,-4(r7); \
85 bdz- L(end2); \
86 lwzu r11,-4(r4); \
87 slwi r9,r10,n; \
88 inslwi r9,r11,n,32-n; \
89 stwu r9,-4(r7); \
90 bdnz L(n); \
91 b L(end1)
92
93 DO_LSHIFT(1)
94 DO_LSHIFT(2)
95 DO_LSHIFT(3)
96 DO_LSHIFT(4)
97 DO_LSHIFT(5)
98 DO_LSHIFT(6)
99 DO_LSHIFT(7)
100 DO_LSHIFT(8)
101 DO_LSHIFT(9)
102 DO_LSHIFT(10)
103 DO_LSHIFT(11)
104 DO_LSHIFT(12)
105 DO_LSHIFT(13)
106 DO_LSHIFT(14)
107 DO_LSHIFT(15)
108 DO_LSHIFT(16)
109 DO_LSHIFT(17)
110 DO_LSHIFT(18)
111 DO_LSHIFT(19)
112 DO_LSHIFT(20)
113 DO_LSHIFT(21)
114 DO_LSHIFT(22)
115 DO_LSHIFT(23)
116 DO_LSHIFT(24)
117 DO_LSHIFT(25)
118 DO_LSHIFT(26)
119 DO_LSHIFT(27)
120 DO_LSHIFT(28)
121 DO_LSHIFT(29)
122 DO_LSHIFT(30)
123 DO_LSHIFT(31)
124
125END (__mpn_lshift)
126

source code of glibc/sysdeps/powerpc/powerpc32/lshift.S