Merge tag 'sched-urgent-2020-12-27' of git://git.kernel.org/pub/scm/linux/kernel...
[linux/fpc-iii.git] / arch / powerpc / lib / checksum_64.S
blob98ff51bd2f7dcc1e97f102ec2487ddc25d037f3c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * This file contains assembly-language implementations
4  * of IP-style 1's complement checksum routines.
5  *      
6  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
7  *
8  * Severely hacked about by Paul Mackerras (paulus@cs.anu.edu.au).
9  */
11 #include <linux/sys.h>
12 #include <asm/processor.h>
13 #include <asm/errno.h>
14 #include <asm/ppc_asm.h>
15 #include <asm/export.h>
18  * Computes the checksum of a memory block at buff, length len,
19  * and adds in "sum" (32-bit).
20  *
21  * __csum_partial(r3=buff, r4=len, r5=sum)
22  */
23 _GLOBAL(__csum_partial)
24         addic   r0,r5,0                 /* clear carry */
26         srdi.   r6,r4,3                 /* less than 8 bytes? */
27         beq     .Lcsum_tail_word
29         /*
30          * If only halfword aligned, align to a double word. Since odd
31          * aligned addresses should be rare and they would require more
32          * work to calculate the correct checksum, we ignore that case
33          * and take the potential slowdown of unaligned loads.
34          */
35         rldicl. r6,r3,64-1,64-2         /* r6 = (r3 >> 1) & 0x3 */
36         beq     .Lcsum_aligned
38         li      r7,4
39         sub     r6,r7,r6
40         mtctr   r6
43         lhz     r6,0(r3)                /* align to doubleword */
44         subi    r4,r4,2
45         addi    r3,r3,2
46         adde    r0,r0,r6
47         bdnz    1b
49 .Lcsum_aligned:
50         /*
51          * We unroll the loop such that each iteration is 64 bytes with an
52          * entry and exit limb of 64 bytes, meaning a minimum size of
53          * 128 bytes.
54          */
55         srdi.   r6,r4,7
56         beq     .Lcsum_tail_doublewords         /* len < 128 */
58         srdi    r6,r4,6
59         subi    r6,r6,1
60         mtctr   r6
62         stdu    r1,-STACKFRAMESIZE(r1)
63         std     r14,STK_REG(R14)(r1)
64         std     r15,STK_REG(R15)(r1)
65         std     r16,STK_REG(R16)(r1)
67         ld      r6,0(r3)
68         ld      r9,8(r3)
70         ld      r10,16(r3)
71         ld      r11,24(r3)
73         /*
74          * On POWER6 and POWER7 back to back adde instructions take 2 cycles
75          * because of the XER dependency. This means the fastest this loop can
76          * go is 16 cycles per iteration. The scheduling of the loop below has
77          * been shown to hit this on both POWER6 and POWER7.
78          */
79         .align 5
81         adde    r0,r0,r6
82         ld      r12,32(r3)
83         ld      r14,40(r3)
85         adde    r0,r0,r9
86         ld      r15,48(r3)
87         ld      r16,56(r3)
88         addi    r3,r3,64
90         adde    r0,r0,r10
92         adde    r0,r0,r11
94         adde    r0,r0,r12
96         adde    r0,r0,r14
98         adde    r0,r0,r15
99         ld      r6,0(r3)
100         ld      r9,8(r3)
102         adde    r0,r0,r16
103         ld      r10,16(r3)
104         ld      r11,24(r3)
105         bdnz    2b
108         adde    r0,r0,r6
109         ld      r12,32(r3)
110         ld      r14,40(r3)
112         adde    r0,r0,r9
113         ld      r15,48(r3)
114         ld      r16,56(r3)
115         addi    r3,r3,64
117         adde    r0,r0,r10
118         adde    r0,r0,r11
119         adde    r0,r0,r12
120         adde    r0,r0,r14
121         adde    r0,r0,r15
122         adde    r0,r0,r16
124         ld      r14,STK_REG(R14)(r1)
125         ld      r15,STK_REG(R15)(r1)
126         ld      r16,STK_REG(R16)(r1)
127         addi    r1,r1,STACKFRAMESIZE
129         andi.   r4,r4,63
131 .Lcsum_tail_doublewords:                /* Up to 127 bytes to go */
132         srdi.   r6,r4,3
133         beq     .Lcsum_tail_word
135         mtctr   r6
137         ld      r6,0(r3)
138         addi    r3,r3,8
139         adde    r0,r0,r6
140         bdnz    3b
142         andi.   r4,r4,7
144 .Lcsum_tail_word:                       /* Up to 7 bytes to go */
145         srdi.   r6,r4,2
146         beq     .Lcsum_tail_halfword
148         lwz     r6,0(r3)
149         addi    r3,r3,4
150         adde    r0,r0,r6
151         subi    r4,r4,4
153 .Lcsum_tail_halfword:                   /* Up to 3 bytes to go */
154         srdi.   r6,r4,1
155         beq     .Lcsum_tail_byte
157         lhz     r6,0(r3)
158         addi    r3,r3,2
159         adde    r0,r0,r6
160         subi    r4,r4,2
162 .Lcsum_tail_byte:                       /* Up to 1 byte to go */
163         andi.   r6,r4,1
164         beq     .Lcsum_finish
166         lbz     r6,0(r3)
167 #ifdef __BIG_ENDIAN__
168         sldi    r9,r6,8                 /* Pad the byte out to 16 bits */
169         adde    r0,r0,r9
170 #else
171         adde    r0,r0,r6
172 #endif
174 .Lcsum_finish:
175         addze   r0,r0                   /* add in final carry */
176         rldicl  r4,r0,32,0              /* fold two 32 bit halves together */
177         add     r3,r4,r0
178         srdi    r3,r3,32
179         blr
180 EXPORT_SYMBOL(__csum_partial)
183         .macro srcnr
184 100:
185         EX_TABLE(100b,.Lerror_nr)
186         .endm
188         .macro source
189 150:
190         EX_TABLE(150b,.Lerror)
191         .endm
193         .macro dstnr
194 200:
195         EX_TABLE(200b,.Lerror_nr)
196         .endm
198         .macro dest
199 250:
200         EX_TABLE(250b,.Lerror)
201         .endm
204  * Computes the checksum of a memory block at src, length len,
205  * and adds in 0xffffffff (32-bit), while copying the block to dst.
206  * If an access exception occurs, it returns 0.
208  * csum_partial_copy_generic(r3=src, r4=dst, r5=len)
209  */
210 _GLOBAL(csum_partial_copy_generic)
211         li      r6,-1
212         addic   r0,r6,0                 /* clear carry */
214         srdi.   r6,r5,3                 /* less than 8 bytes? */
215         beq     .Lcopy_tail_word
217         /*
218          * If only halfword aligned, align to a double word. Since odd
219          * aligned addresses should be rare and they would require more
220          * work to calculate the correct checksum, we ignore that case
221          * and take the potential slowdown of unaligned loads.
222          *
223          * If the source and destination are relatively unaligned we only
224          * align the source. This keeps things simple.
225          */
226         rldicl. r6,r3,64-1,64-2         /* r6 = (r3 >> 1) & 0x3 */
227         beq     .Lcopy_aligned
229         li      r9,4
230         sub     r6,r9,r6
231         mtctr   r6
234 srcnr;  lhz     r6,0(r3)                /* align to doubleword */
235         subi    r5,r5,2
236         addi    r3,r3,2
237         adde    r0,r0,r6
238 dstnr;  sth     r6,0(r4)
239         addi    r4,r4,2
240         bdnz    1b
242 .Lcopy_aligned:
243         /*
244          * We unroll the loop such that each iteration is 64 bytes with an
245          * entry and exit limb of 64 bytes, meaning a minimum size of
246          * 128 bytes.
247          */
248         srdi.   r6,r5,7
249         beq     .Lcopy_tail_doublewords         /* len < 128 */
251         srdi    r6,r5,6
252         subi    r6,r6,1
253         mtctr   r6
255         stdu    r1,-STACKFRAMESIZE(r1)
256         std     r14,STK_REG(R14)(r1)
257         std     r15,STK_REG(R15)(r1)
258         std     r16,STK_REG(R16)(r1)
260 source; ld      r6,0(r3)
261 source; ld      r9,8(r3)
263 source; ld      r10,16(r3)
264 source; ld      r11,24(r3)
266         /*
267          * On POWER6 and POWER7 back to back adde instructions take 2 cycles
268          * because of the XER dependency. This means the fastest this loop can
269          * go is 16 cycles per iteration. The scheduling of the loop below has
270          * been shown to hit this on both POWER6 and POWER7.
271          */
272         .align 5
274         adde    r0,r0,r6
275 source; ld      r12,32(r3)
276 source; ld      r14,40(r3)
278         adde    r0,r0,r9
279 source; ld      r15,48(r3)
280 source; ld      r16,56(r3)
281         addi    r3,r3,64
283         adde    r0,r0,r10
284 dest;   std     r6,0(r4)
285 dest;   std     r9,8(r4)
287         adde    r0,r0,r11
288 dest;   std     r10,16(r4)
289 dest;   std     r11,24(r4)
291         adde    r0,r0,r12
292 dest;   std     r12,32(r4)
293 dest;   std     r14,40(r4)
295         adde    r0,r0,r14
296 dest;   std     r15,48(r4)
297 dest;   std     r16,56(r4)
298         addi    r4,r4,64
300         adde    r0,r0,r15
301 source; ld      r6,0(r3)
302 source; ld      r9,8(r3)
304         adde    r0,r0,r16
305 source; ld      r10,16(r3)
306 source; ld      r11,24(r3)
307         bdnz    2b
310         adde    r0,r0,r6
311 source; ld      r12,32(r3)
312 source; ld      r14,40(r3)
314         adde    r0,r0,r9
315 source; ld      r15,48(r3)
316 source; ld      r16,56(r3)
317         addi    r3,r3,64
319         adde    r0,r0,r10
320 dest;   std     r6,0(r4)
321 dest;   std     r9,8(r4)
323         adde    r0,r0,r11
324 dest;   std     r10,16(r4)
325 dest;   std     r11,24(r4)
327         adde    r0,r0,r12
328 dest;   std     r12,32(r4)
329 dest;   std     r14,40(r4)
331         adde    r0,r0,r14
332 dest;   std     r15,48(r4)
333 dest;   std     r16,56(r4)
334         addi    r4,r4,64
336         adde    r0,r0,r15
337         adde    r0,r0,r16
339         ld      r14,STK_REG(R14)(r1)
340         ld      r15,STK_REG(R15)(r1)
341         ld      r16,STK_REG(R16)(r1)
342         addi    r1,r1,STACKFRAMESIZE
344         andi.   r5,r5,63
346 .Lcopy_tail_doublewords:                /* Up to 127 bytes to go */
347         srdi.   r6,r5,3
348         beq     .Lcopy_tail_word
350         mtctr   r6
352 srcnr;  ld      r6,0(r3)
353         addi    r3,r3,8
354         adde    r0,r0,r6
355 dstnr;  std     r6,0(r4)
356         addi    r4,r4,8
357         bdnz    3b
359         andi.   r5,r5,7
361 .Lcopy_tail_word:                       /* Up to 7 bytes to go */
362         srdi.   r6,r5,2
363         beq     .Lcopy_tail_halfword
365 srcnr;  lwz     r6,0(r3)
366         addi    r3,r3,4
367         adde    r0,r0,r6
368 dstnr;  stw     r6,0(r4)
369         addi    r4,r4,4
370         subi    r5,r5,4
372 .Lcopy_tail_halfword:                   /* Up to 3 bytes to go */
373         srdi.   r6,r5,1
374         beq     .Lcopy_tail_byte
376 srcnr;  lhz     r6,0(r3)
377         addi    r3,r3,2
378         adde    r0,r0,r6
379 dstnr;  sth     r6,0(r4)
380         addi    r4,r4,2
381         subi    r5,r5,2
383 .Lcopy_tail_byte:                       /* Up to 1 byte to go */
384         andi.   r6,r5,1
385         beq     .Lcopy_finish
387 srcnr;  lbz     r6,0(r3)
388 #ifdef __BIG_ENDIAN__
389         sldi    r9,r6,8                 /* Pad the byte out to 16 bits */
390         adde    r0,r0,r9
391 #else
392         adde    r0,r0,r6
393 #endif
394 dstnr;  stb     r6,0(r4)
396 .Lcopy_finish:
397         addze   r0,r0                   /* add in final carry */
398         rldicl  r4,r0,32,0              /* fold two 32 bit halves together */
399         add     r3,r4,r0
400         srdi    r3,r3,32
401         blr
403 .Lerror:
404         ld      r14,STK_REG(R14)(r1)
405         ld      r15,STK_REG(R15)(r1)
406         ld      r16,STK_REG(R16)(r1)
407         addi    r1,r1,STACKFRAMESIZE
408 .Lerror_nr:
409         li      r3,0
410         blr
412 EXPORT_SYMBOL(csum_partial_copy_generic)
415  * __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
416  *                         const struct in6_addr *daddr,
417  *                         __u32 len, __u8 proto, __wsum sum)
418  */
420 _GLOBAL(csum_ipv6_magic)
421         ld      r8, 0(r3)
422         ld      r9, 8(r3)
423         add     r5, r5, r6
424         addc    r0, r8, r9
425         ld      r10, 0(r4)
426         ld      r11, 8(r4)
427 #ifdef CONFIG_CPU_LITTLE_ENDIAN
428         rotldi  r5, r5, 8
429 #endif
430         adde    r0, r0, r10
431         add     r5, r5, r7
432         adde    r0, r0, r11
433         adde    r0, r0, r5
434         addze   r0, r0
435         rotldi  r3, r0, 32              /* fold two 32 bit halves together */
436         add     r3, r0, r3
437         srdi    r0, r3, 32
438         rotlwi  r3, r0, 16              /* fold two 16 bit halves together */
439         add     r3, r0, r3
440         not     r3, r3
441         rlwinm  r3, r3, 16, 16, 31
442         blr
443 EXPORT_SYMBOL(csum_ipv6_magic)