Update copyright notices with scripts/update-copyrights.
[jlayton/glibc.git] / sysdeps / powerpc / powerpc64 / power7 / memcmp.S
1 /* Optimized memcmp implementation for POWER7/PowerPC64.
2    Copyright (C) 2010-2013 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    <http://www.gnu.org/licenses/>.  */
18
19 #include <sysdep.h>
20 #include <bp-sym.h>
21 #include <bp-asm.h>
22
23 /* int [r3] memcmp (const char *s1 [r3],
24                     const char *s2 [r4],
25                     size_t size [r5])  */
26
27         .machine power7
28 EALIGN (BP_SYM(memcmp),4,0)
29         CALL_MCOUNT 3
30
31 #define rTMP    r0
32 #define rRTN    r3
33 #define rSTR1   r3      /* first string arg */
34 #define rSTR2   r4      /* second string arg */
35 #define rN      r5      /* max string length */
36 /* Note:  The Bounded pointer support in this code is broken.  This code
37    was inherited from PPC32 and that support was never completed.
38    Current PPC gcc does not support -fbounds-check or -fbounded-pointers.  */
39 #define rWORD1  r6      /* current word in s1 */
40 #define rWORD2  r7      /* current word in s2 */
41 #define rWORD3  r8      /* next word in s1 */
42 #define rWORD4  r9      /* next word in s2 */
43 #define rWORD5  r10     /* next word in s1 */
44 #define rWORD6  r11     /* next word in s2 */
45 #define rBITDIF r12     /* bits that differ in s1 & s2 words */
46 #define rWORD7  r30     /* next word in s1 */
47 #define rWORD8  r31     /* next word in s2 */
48
49         xor     rTMP,rSTR2,rSTR1
50         cmpldi  cr6,rN,0
51         cmpldi  cr1,rN,12
52         clrldi. rTMP,rTMP,61
53         clrldi  rBITDIF,rSTR1,61
54         cmpldi  cr5,rBITDIF,0
55         beq-    cr6,L(zeroLength)
56         dcbt    0,rSTR1
57         dcbt    0,rSTR2
58 /* If less than 8 bytes or not aligned, use the unalligned
59    byte loop.  */
60         blt     cr1,L(bytealigned)
61         std     rWORD8,-8(r1)
62         cfi_offset(rWORD8,-8)
63         std     rWORD7,-16(r1)
64         cfi_offset(rWORD7,-16)
65         bne     L(unaligned)
66 /* At this point we know both strings have the same alignment and the
67    compare length is at least 8 bytes.  rBITDIF containes the low order
68    3 bits of rSTR1 and cr5 contains the result of the logical compare
69    of rBITDIF to 0.  If rBITDIF == 0 then we are already double word
70    aligned and can perform the DWaligned loop.
71
72    Otherwise we know the two strings have the same alignment (but not
73    yet DW).  So we can force the string addresses to the next lower DW
74    boundary and special case this first DW word using shift left to
75    ellimiate bits preceeding the first byte.  Since we want to join the
76    normal (DWaligned) compare loop, starting at the second double word,
77    we need to adjust the length (rN) and special case the loop
78    versioning for the first DW. This insures that the loop count is
79    correct and the first DW (shifted) is in the expected resister pair.  */
80         .align  4
81 L(samealignment):
82         clrrdi  rSTR1,rSTR1,3
83         clrrdi  rSTR2,rSTR2,3
84         beq     cr5,L(DWaligned)
85         add     rN,rN,rBITDIF
86         sldi    r11,rBITDIF,3
87         srdi    rTMP,rN,5       /* Divide by 32 */
88         andi.   rBITDIF,rN,24   /* Get the DW remainder */
89         ld      rWORD1,0(rSTR1)
90         ld      rWORD2,0(rSTR2)
91         cmpldi  cr1,rBITDIF,16
92         cmpldi  cr7,rN,32
93         clrldi  rN,rN,61
94         beq     L(dPs4)
95         mtctr   rTMP
96         bgt     cr1,L(dPs3)
97         beq     cr1,L(dPs2)
98
99 /* Remainder is 8 */
100         .align  3
101 L(dsP1):
102         sld     rWORD5,rWORD1,r11
103         sld     rWORD6,rWORD2,r11
104         cmpld   cr5,rWORD5,rWORD6
105         blt     cr7,L(dP1x)
106 /* Do something useful in this cycle since we have to branch anyway.  */
107         ld      rWORD1,8(rSTR1)
108         ld      rWORD2,8(rSTR2)
109         cmpld   cr0,rWORD1,rWORD2
110         b       L(dP1e)
111 /* Remainder is 16 */
112         .align  4
113 L(dPs2):
114         sld     rWORD5,rWORD1,r11
115         sld     rWORD6,rWORD2,r11
116         cmpld   cr6,rWORD5,rWORD6
117         blt     cr7,L(dP2x)
118 /* Do something useful in this cycle since we have to branch anyway.  */
119         ld      rWORD7,8(rSTR1)
120         ld      rWORD8,8(rSTR2)
121         cmpld   cr5,rWORD7,rWORD8
122         b       L(dP2e)
123 /* Remainder is 24 */
124         .align  4
125 L(dPs3):
126         sld     rWORD3,rWORD1,r11
127         sld     rWORD4,rWORD2,r11
128         cmpld   cr1,rWORD3,rWORD4
129         b       L(dP3e)
130 /* Count is a multiple of 32, remainder is 0 */
131         .align  4
132 L(dPs4):
133         mtctr   rTMP
134         sld     rWORD1,rWORD1,r11
135         sld     rWORD2,rWORD2,r11
136         cmpld   cr0,rWORD1,rWORD2
137         b       L(dP4e)
138
139 /* At this point we know both strings are double word aligned and the
140    compare length is at least 8 bytes.  */
141         .align  4
142 L(DWaligned):
143         andi.   rBITDIF,rN,24   /* Get the DW remainder */
144         srdi    rTMP,rN,5       /* Divide by 32 */
145         cmpldi  cr1,rBITDIF,16
146         cmpldi  cr7,rN,32
147         clrldi  rN,rN,61
148         beq     L(dP4)
149         bgt     cr1,L(dP3)
150         beq     cr1,L(dP2)
151
152 /* Remainder is 8 */
153         .align  4
154 L(dP1):
155         mtctr   rTMP
156 /* Normally we'd use rWORD7/rWORD8 here, but since we might exit early
157    (8-15 byte compare), we want to use only volitile registers.  This
158    means we can avoid restoring non-volitile registers since we did not
159    change any on the early exit path.  The key here is the non-early
160    exit path only cares about the condition code (cr5), not about which
161    register pair was used.  */
162         ld      rWORD5,0(rSTR1)
163         ld      rWORD6,0(rSTR2)
164         cmpld   cr5,rWORD5,rWORD6
165         blt     cr7,L(dP1x)
166         ld      rWORD1,8(rSTR1)
167         ld      rWORD2,8(rSTR2)
168         cmpld   cr0,rWORD1,rWORD2
169 L(dP1e):
170         ld      rWORD3,16(rSTR1)
171         ld      rWORD4,16(rSTR2)
172         cmpld   cr1,rWORD3,rWORD4
173         ld      rWORD5,24(rSTR1)
174         ld      rWORD6,24(rSTR2)
175         cmpld   cr6,rWORD5,rWORD6
176         bne     cr5,L(dLcr5)
177         bne     cr0,L(dLcr0)
178
179         ldu     rWORD7,32(rSTR1)
180         ldu     rWORD8,32(rSTR2)
181         bne     cr1,L(dLcr1)
182         cmpld   cr5,rWORD7,rWORD8
183         bdnz    L(dLoop)
184         bne     cr6,L(dLcr6)
185         ld      rWORD8,-8(r1)
186         ld      rWORD7,-16(r1)
187         .align  3
188 L(dP1x):
189         sldi.   r12,rN,3
190         bne     cr5,L(dLcr5)
191         subfic  rN,r12,64       /* Shift count is 64 - (rN * 8).  */
192         bne     L(d00)
193         li      rRTN,0
194         blr
195
196 /* Remainder is 16 */
197         .align  4
198 L(dP2):
199         mtctr   rTMP
200         ld      rWORD5,0(rSTR1)
201         ld      rWORD6,0(rSTR2)
202         cmpld   cr6,rWORD5,rWORD6
203         blt     cr7,L(dP2x)
204         ld      rWORD7,8(rSTR1)
205         ld      rWORD8,8(rSTR2)
206         cmpld   cr5,rWORD7,rWORD8
207 L(dP2e):
208         ld      rWORD1,16(rSTR1)
209         ld      rWORD2,16(rSTR2)
210         cmpld   cr0,rWORD1,rWORD2
211         ld      rWORD3,24(rSTR1)
212         ld      rWORD4,24(rSTR2)
213         cmpld   cr1,rWORD3,rWORD4
214         addi    rSTR1,rSTR1,8
215         addi    rSTR2,rSTR2,8
216         bne     cr6,L(dLcr6)
217         bne     cr5,L(dLcr5)
218         b       L(dLoop2)
219 /* Again we are on a early exit path (16-23 byte compare), we want to
220    only use volitile registers and avoid restoring non-volitile
221    registers.  */
222         .align  4
223 L(dP2x):
224         ld      rWORD3,8(rSTR1)
225         ld      rWORD4,8(rSTR2)
226         cmpld   cr5,rWORD3,rWORD4
227         sldi.   r12,rN,3
228         bne     cr6,L(dLcr6)
229         addi    rSTR1,rSTR1,8
230         addi    rSTR2,rSTR2,8
231         bne     cr5,L(dLcr5)
232         subfic  rN,r12,64       /* Shift count is 64 - (rN * 8).  */
233         bne     L(d00)
234         li      rRTN,0
235         blr
236
237 /* Remainder is 24 */
238         .align  4
239 L(dP3):
240         mtctr   rTMP
241         ld      rWORD3,0(rSTR1)
242         ld      rWORD4,0(rSTR2)
243         cmpld   cr1,rWORD3,rWORD4
244 L(dP3e):
245         ld      rWORD5,8(rSTR1)
246         ld      rWORD6,8(rSTR2)
247         cmpld   cr6,rWORD5,rWORD6
248         blt     cr7,L(dP3x)
249         ld      rWORD7,16(rSTR1)
250         ld      rWORD8,16(rSTR2)
251         cmpld   cr5,rWORD7,rWORD8
252         ld      rWORD1,24(rSTR1)
253         ld      rWORD2,24(rSTR2)
254         cmpld   cr0,rWORD1,rWORD2
255         addi    rSTR1,rSTR1,16
256         addi    rSTR2,rSTR2,16
257         bne     cr1,L(dLcr1)
258         bne     cr6,L(dLcr6)
259         b       L(dLoop1)
260 /* Again we are on a early exit path (24-31 byte compare), we want to
261    only use volitile registers and avoid restoring non-volitile
262    registers.  */
263         .align  4
264 L(dP3x):
265         ld      rWORD1,16(rSTR1)
266         ld      rWORD2,16(rSTR2)
267         cmpld   cr5,rWORD1,rWORD2
268         sldi.   r12,rN,3
269         bne     cr1,L(dLcr1)
270         addi    rSTR1,rSTR1,16
271         addi    rSTR2,rSTR2,16
272         bne     cr6,L(dLcr6)
273         subfic  rN,r12,64       /* Shift count is 64 - (rN * 8).  */
274         bne     cr5,L(dLcr5)
275         bne     L(d00)
276         li      rRTN,0
277         blr
278
279 /* Count is a multiple of 32, remainder is 0 */
280         .align  4
281 L(dP4):
282         mtctr   rTMP
283         ld      rWORD1,0(rSTR1)
284         ld      rWORD2,0(rSTR2)
285         cmpld   cr0,rWORD1,rWORD2
286 L(dP4e):
287         ld      rWORD3,8(rSTR1)
288         ld      rWORD4,8(rSTR2)
289         cmpld   cr1,rWORD3,rWORD4
290         ld      rWORD5,16(rSTR1)
291         ld      rWORD6,16(rSTR2)
292         cmpld   cr6,rWORD5,rWORD6
293         ldu     rWORD7,24(rSTR1)
294         ldu     rWORD8,24(rSTR2)
295         cmpld   cr5,rWORD7,rWORD8
296         bne     cr0,L(dLcr0)
297         bne     cr1,L(dLcr1)
298         bdz-    L(d24)          /* Adjust CTR as we start with +4 */
299 /* This is the primary loop */
300         .align  4
301 L(dLoop):
302         ld      rWORD1,8(rSTR1)
303         ld      rWORD2,8(rSTR2)
304         cmpld   cr1,rWORD3,rWORD4
305         bne     cr6,L(dLcr6)
306 L(dLoop1):
307         ld      rWORD3,16(rSTR1)
308         ld      rWORD4,16(rSTR2)
309         cmpld   cr6,rWORD5,rWORD6
310         bne     cr5,L(dLcr5)
311 L(dLoop2):
312         ld      rWORD5,24(rSTR1)
313         ld      rWORD6,24(rSTR2)
314         cmpld   cr5,rWORD7,rWORD8
315         bne     cr0,L(dLcr0)
316 L(dLoop3):
317         ldu     rWORD7,32(rSTR1)
318         ldu     rWORD8,32(rSTR2)
319         bne     cr1,L(dLcr1)
320         cmpld   cr0,rWORD1,rWORD2
321         bdnz    L(dLoop)
322
323 L(dL4):
324         cmpld   cr1,rWORD3,rWORD4
325         bne     cr6,L(dLcr6)
326         cmpld   cr6,rWORD5,rWORD6
327         bne     cr5,L(dLcr5)
328         cmpld   cr5,rWORD7,rWORD8
329 L(d44):
330         bne     cr0,L(dLcr0)
331 L(d34):
332         bne     cr1,L(dLcr1)
333 L(d24):
334         bne     cr6,L(dLcr6)
335 L(d14):
336         sldi.   r12,rN,3
337         bne     cr5,L(dLcr5)
338 L(d04):
339         ld      rWORD8,-8(r1)
340         ld      rWORD7,-16(r1)
341         subfic  rN,r12,64       /* Shift count is 64 - (rN * 8).  */
342         beq     L(zeroLength)
343 /* At this point we have a remainder of 1 to 7 bytes to compare.  Since
344    we are aligned it is safe to load the whole double word, and use
345    shift right double to elliminate bits beyond the compare length.  */
346 L(d00):
347         ld      rWORD1,8(rSTR1)
348         ld      rWORD2,8(rSTR2)
349         srd     rWORD1,rWORD1,rN
350         srd     rWORD2,rWORD2,rN
351         cmpld   cr5,rWORD1,rWORD2
352         bne     cr5,L(dLcr5x)
353         li      rRTN,0
354         blr
355         .align  4
356 L(dLcr0):
357         ld      rWORD8,-8(r1)
358         ld      rWORD7,-16(r1)
359         li      rRTN,1
360         bgtlr   cr0
361         li      rRTN,-1
362         blr
363         .align  4
364 L(dLcr1):
365         ld      rWORD8,-8(r1)
366         ld      rWORD7,-16(r1)
367         li      rRTN,1
368         bgtlr   cr1
369         li      rRTN,-1
370         blr
371         .align  4
372 L(dLcr6):
373         ld      rWORD8,-8(r1)
374         ld      rWORD7,-16(r1)
375         li      rRTN,1
376         bgtlr   cr6
377         li      rRTN,-1
378         blr
379         .align  4
380 L(dLcr5):
381         ld      rWORD8,-8(r1)
382         ld      rWORD7,-16(r1)
383 L(dLcr5x):
384         li      rRTN,1
385         bgtlr   cr5
386         li      rRTN,-1
387         blr
388
389         .align  4
390 L(bytealigned):
391         mtctr   rN
392         beq     cr6,L(zeroLength)
393
394 /* We need to prime this loop.  This loop is swing modulo scheduled
395    to avoid pipe delays.  The dependent instruction latencies (load to
396    compare to conditional branch) is 2 to 3 cycles.  In this loop each
397    dispatch group ends in a branch and takes 1 cycle.  Effectively
398    the first iteration of the loop only serves to load operands and
399    branches based on compares are delayed until the next loop.
400
401    So we must precondition some registers and condition codes so that
402    we don't exit the loop early on the first iteration.  */
403
404         lbz     rWORD1,0(rSTR1)
405         lbz     rWORD2,0(rSTR2)
406         bdz     L(b11)
407         cmpld   cr0,rWORD1,rWORD2
408         lbz     rWORD3,1(rSTR1)
409         lbz     rWORD4,1(rSTR2)
410         bdz     L(b12)
411         cmpld   cr1,rWORD3,rWORD4
412         lbzu    rWORD5,2(rSTR1)
413         lbzu    rWORD6,2(rSTR2)
414         bdz     L(b13)
415         .align  4
416 L(bLoop):
417         lbzu    rWORD1,1(rSTR1)
418         lbzu    rWORD2,1(rSTR2)
419         bne     cr0,L(bLcr0)
420
421         cmpld   cr6,rWORD5,rWORD6
422         bdz     L(b3i)
423
424         lbzu    rWORD3,1(rSTR1)
425         lbzu    rWORD4,1(rSTR2)
426         bne     cr1,L(bLcr1)
427
428         cmpld   cr0,rWORD1,rWORD2
429         bdz     L(b2i)
430
431         lbzu    rWORD5,1(rSTR1)
432         lbzu    rWORD6,1(rSTR2)
433         bne     cr6,L(bLcr6)
434
435         cmpld   cr1,rWORD3,rWORD4
436         bdnz    L(bLoop)
437
438 /* We speculatively loading bytes before we have tested the previous
439    bytes.  But we must avoid overrunning the length (in the ctr) to
440    prevent these speculative loads from causing a segfault.  In this
441    case the loop will exit early (before the all pending bytes are
442    tested.  In this case we must complete the pending operations
443    before returning.  */
444 L(b1i):
445         bne     cr0,L(bLcr0)
446         bne     cr1,L(bLcr1)
447         b       L(bx56)
448         .align  4
449 L(b2i):
450         bne     cr6,L(bLcr6)
451         bne     cr0,L(bLcr0)
452         b       L(bx34)
453         .align  4
454 L(b3i):
455         bne     cr1,L(bLcr1)
456         bne     cr6,L(bLcr6)
457         b       L(bx12)
458         .align  4
459 L(bLcr0):
460         li      rRTN,1
461         bgtlr   cr0
462         li      rRTN,-1
463         blr
464 L(bLcr1):
465         li      rRTN,1
466         bgtlr   cr1
467         li      rRTN,-1
468         blr
469 L(bLcr6):
470         li      rRTN,1
471         bgtlr   cr6
472         li      rRTN,-1
473         blr
474
475 L(b13):
476         bne     cr0,L(bx12)
477         bne     cr1,L(bx34)
478 L(bx56):
479         sub     rRTN,rWORD5,rWORD6
480         blr
481         nop
482 L(b12):
483         bne     cr0,L(bx12)
484 L(bx34):
485         sub     rRTN,rWORD3,rWORD4
486         blr
487 L(b11):
488 L(bx12):
489         sub     rRTN,rWORD1,rWORD2
490         blr
491         .align  4
492 L(zeroLengthReturn):
493         ld      rWORD8,-8(r1)
494         ld      rWORD7,-16(r1)
495 L(zeroLength):
496         li      rRTN,0
497         blr
498
499         .align  4
500 /* At this point we know the strings have different alignment and the
501    compare length is at least 8 bytes.  rBITDIF containes the low order
502    3 bits of rSTR1 and cr5 contains the result of the logical compare
503    of rBITDIF to 0.  If rBITDIF == 0 then rStr1 is double word
504    aligned and can perform the DWunaligned loop.
505
506    Otherwise we know that rSTR1 is not aready DW aligned yet.
507    So we can force the string addresses to the next lower DW
508    boundary and special case this first DW word using shift left to
509    ellimiate bits preceeding the first byte.  Since we want to join the
510    normal (DWaligned) compare loop, starting at the second double word,
511    we need to adjust the length (rN) and special case the loop
512    versioning for the first DW. This insures that the loop count is
513    correct and the first DW (shifted) is in the expected resister pair.  */
514 #define rSHL    r29     /* Unaligned shift left count.  */
515 #define rSHR    r28     /* Unaligned shift right count.  */
516 #define rB              r27     /* Left rotation temp for rWORD2.  */
517 #define rD              r26     /* Left rotation temp for rWORD4.  */
518 #define rF              r25     /* Left rotation temp for rWORD6.  */
519 #define rH              r24     /* Left rotation temp for rWORD8.  */
520 #define rA              r0      /* Right rotation temp for rWORD2.  */
521 #define rC              r12     /* Right rotation temp for rWORD4.  */
522 #define rE              r0      /* Right rotation temp for rWORD6.  */
523 #define rG              r12     /* Right rotation temp for rWORD8.  */
524 L(unaligned):
525         std     r29,-24(r1)
526         cfi_offset(r29,-24)
527         clrldi  rSHL,rSTR2,61
528         beq     cr6,L(duzeroLength)
529         std     r28,-32(r1)
530         cfi_offset(r28,-32)
531         beq     cr5,L(DWunaligned)
532         std     r27,-40(r1)
533         cfi_offset(r27,-40)
534 /* Adjust the logical start of rSTR2 ro compensate for the extra bits
535    in the 1st rSTR1 DW.  */
536         sub     r27,rSTR2,rBITDIF
537 /* But do not attempt to address the DW before that DW that contains
538    the actual start of rSTR2.  */
539         clrrdi  rSTR2,rSTR2,3
540         std     r26,-48(r1)
541         cfi_offset(r26,-48)
542 /* Compute the leaft/right shift counts for the unalign rSTR2,
543    compensating for the logical (DW aligned) start of rSTR1.  */
544         clrldi  rSHL,r27,61
545         clrrdi  rSTR1,rSTR1,3
546         std     r25,-56(r1)
547         cfi_offset(r25,-56)
548         sldi    rSHL,rSHL,3
549         cmpld   cr5,r27,rSTR2
550         add     rN,rN,rBITDIF
551         sldi    r11,rBITDIF,3
552         std     r24,-64(r1)
553         cfi_offset(r24,-64)
554         subfic  rSHR,rSHL,64
555         srdi    rTMP,rN,5       /* Divide by 32 */
556         andi.   rBITDIF,rN,24   /* Get the DW remainder */
557 /* We normally need to load 2 DWs to start the unaligned rSTR2, but in
558    this special case those bits may be discarded anyway.  Also we
559    must avoid loading a DW where none of the bits are part of rSTR2 as
560    this may cross a page boundary and cause a page fault.  */
561         li      rWORD8,0
562         blt     cr5,L(dus0)
563         ld      rWORD8,0(rSTR2)
564         la      rSTR2,8(rSTR2)
565         sld     rWORD8,rWORD8,rSHL
566
567 L(dus0):
568         ld      rWORD1,0(rSTR1)
569         ld      rWORD2,0(rSTR2)
570         cmpldi  cr1,rBITDIF,16
571         cmpldi  cr7,rN,32
572         srd     rG,rWORD2,rSHR
573         clrldi  rN,rN,61
574         beq     L(duPs4)
575         mtctr   rTMP
576         or      rWORD8,rG,rWORD8
577         bgt     cr1,L(duPs3)
578         beq     cr1,L(duPs2)
579
580 /* Remainder is 8 */
581         .align  4
582 L(dusP1):
583         sld     rB,rWORD2,rSHL
584         sld     rWORD7,rWORD1,r11
585         sld     rWORD8,rWORD8,r11
586         bge     cr7,L(duP1e)
587 /* At this point we exit early with the first double word compare
588    complete and remainder of 0 to 7 bytes.  See L(du14) for details on
589    how we handle the remaining bytes.  */
590         cmpld   cr5,rWORD7,rWORD8
591         sldi.   rN,rN,3
592         bne     cr5,L(duLcr5)
593         cmpld   cr7,rN,rSHR
594         beq     L(duZeroReturn)
595         li      rA,0
596         ble     cr7,L(dutrim)
597         ld      rWORD2,8(rSTR2)
598         srd     rA,rWORD2,rSHR
599         b       L(dutrim)
600 /* Remainder is 16 */
601         .align  4
602 L(duPs2):
603         sld     rH,rWORD2,rSHL
604         sld     rWORD5,rWORD1,r11
605         sld     rWORD6,rWORD8,r11
606         b       L(duP2e)
607 /* Remainder is 24 */
608         .align  4
609 L(duPs3):
610         sld     rF,rWORD2,rSHL
611         sld     rWORD3,rWORD1,r11
612         sld     rWORD4,rWORD8,r11
613         b       L(duP3e)
614 /* Count is a multiple of 32, remainder is 0 */
615         .align  4
616 L(duPs4):
617         mtctr   rTMP
618         or      rWORD8,rG,rWORD8
619         sld     rD,rWORD2,rSHL
620         sld     rWORD1,rWORD1,r11
621         sld     rWORD2,rWORD8,r11
622         b       L(duP4e)
623
624 /* At this point we know rSTR1 is double word aligned and the
625    compare length is at least 8 bytes.  */
626         .align  4
627 L(DWunaligned):
628         std     r27,-40(r1)
629         cfi_offset(r27,-40)
630         clrrdi  rSTR2,rSTR2,3
631         std     r26,-48(r1)
632         cfi_offset(r26,-48)
633         srdi    rTMP,rN,5       /* Divide by 32 */
634         std     r25,-56(r1)
635         cfi_offset(r25,-56)
636         andi.   rBITDIF,rN,24   /* Get the DW remainder */
637         std     r24,-64(r1)
638         cfi_offset(r24,-64)
639         sldi    rSHL,rSHL,3
640         ld      rWORD6,0(rSTR2)
641         ldu     rWORD8,8(rSTR2)
642         cmpldi  cr1,rBITDIF,16
643         cmpldi  cr7,rN,32
644         clrldi  rN,rN,61
645         subfic  rSHR,rSHL,64
646         sld     rH,rWORD6,rSHL
647         beq     L(duP4)
648         mtctr   rTMP
649         bgt     cr1,L(duP3)
650         beq     cr1,L(duP2)
651
652 /* Remainder is 8 */
653         .align  4
654 L(duP1):
655         srd     rG,rWORD8,rSHR
656         ld      rWORD7,0(rSTR1)
657         sld     rB,rWORD8,rSHL
658         or      rWORD8,rG,rH
659         blt     cr7,L(duP1x)
660 L(duP1e):
661         ld      rWORD1,8(rSTR1)
662         ld      rWORD2,8(rSTR2)
663         cmpld   cr5,rWORD7,rWORD8
664         srd     rA,rWORD2,rSHR
665         sld     rD,rWORD2,rSHL
666         or      rWORD2,rA,rB
667         ld      rWORD3,16(rSTR1)
668         ld      rWORD4,16(rSTR2)
669         cmpld   cr0,rWORD1,rWORD2
670         srd     rC,rWORD4,rSHR
671         sld     rF,rWORD4,rSHL
672         bne     cr5,L(duLcr5)
673         or      rWORD4,rC,rD
674         ld      rWORD5,24(rSTR1)
675         ld      rWORD6,24(rSTR2)
676         cmpld   cr1,rWORD3,rWORD4
677         srd     rE,rWORD6,rSHR
678         sld     rH,rWORD6,rSHL
679         bne     cr0,L(duLcr0)
680         or      rWORD6,rE,rF
681         cmpld   cr6,rWORD5,rWORD6
682         b       L(duLoop3)
683         .align  4
684 /* At this point we exit early with the first double word compare
685    complete and remainder of 0 to 7 bytes.  See L(du14) for details on
686    how we handle the remaining bytes.  */
687 L(duP1x):
688         cmpld   cr5,rWORD7,rWORD8
689         sldi.   rN,rN,3
690         bne     cr5,L(duLcr5)
691         cmpld   cr7,rN,rSHR
692         beq     L(duZeroReturn)
693         li      rA,0
694         ble     cr7,L(dutrim)
695         ld      rWORD2,8(rSTR2)
696         srd     rA,rWORD2,rSHR
697         b       L(dutrim)
698 /* Remainder is 16 */
699         .align  4
700 L(duP2):
701         srd     rE,rWORD8,rSHR
702         ld      rWORD5,0(rSTR1)
703         or      rWORD6,rE,rH
704         sld     rH,rWORD8,rSHL
705 L(duP2e):
706         ld      rWORD7,8(rSTR1)
707         ld      rWORD8,8(rSTR2)
708         cmpld   cr6,rWORD5,rWORD6
709         srd     rG,rWORD8,rSHR
710         sld     rB,rWORD8,rSHL
711         or      rWORD8,rG,rH
712         blt     cr7,L(duP2x)
713         ld      rWORD1,16(rSTR1)
714         ld      rWORD2,16(rSTR2)
715         cmpld   cr5,rWORD7,rWORD8
716         bne     cr6,L(duLcr6)
717         srd     rA,rWORD2,rSHR
718         sld     rD,rWORD2,rSHL
719         or      rWORD2,rA,rB
720         ld      rWORD3,24(rSTR1)
721         ld      rWORD4,24(rSTR2)
722         cmpld   cr0,rWORD1,rWORD2
723         bne     cr5,L(duLcr5)
724         srd     rC,rWORD4,rSHR
725         sld     rF,rWORD4,rSHL
726         or      rWORD4,rC,rD
727         addi    rSTR1,rSTR1,8
728         addi    rSTR2,rSTR2,8
729         cmpld   cr1,rWORD3,rWORD4
730         b       L(duLoop2)
731         .align  4
732 L(duP2x):
733         cmpld   cr5,rWORD7,rWORD8
734         addi    rSTR1,rSTR1,8
735         addi    rSTR2,rSTR2,8
736         bne     cr6,L(duLcr6)
737         sldi.   rN,rN,3
738         bne     cr5,L(duLcr5)
739         cmpld   cr7,rN,rSHR
740         beq     L(duZeroReturn)
741         li      rA,0
742         ble     cr7,L(dutrim)
743         ld      rWORD2,8(rSTR2)
744         srd     rA,rWORD2,rSHR
745         b       L(dutrim)
746
747 /* Remainder is 24 */
748         .align  4
749 L(duP3):
750         srd     rC,rWORD8,rSHR
751         ld      rWORD3,0(rSTR1)
752         sld     rF,rWORD8,rSHL
753         or      rWORD4,rC,rH
754 L(duP3e):
755         ld      rWORD5,8(rSTR1)
756         ld      rWORD6,8(rSTR2)
757         cmpld   cr1,rWORD3,rWORD4
758         srd     rE,rWORD6,rSHR
759         sld     rH,rWORD6,rSHL
760         or      rWORD6,rE,rF
761         ld      rWORD7,16(rSTR1)
762         ld      rWORD8,16(rSTR2)
763         cmpld   cr6,rWORD5,rWORD6
764         bne     cr1,L(duLcr1)
765         srd     rG,rWORD8,rSHR
766         sld     rB,rWORD8,rSHL
767         or      rWORD8,rG,rH
768         blt     cr7,L(duP3x)
769         ld      rWORD1,24(rSTR1)
770         ld      rWORD2,24(rSTR2)
771         cmpld   cr5,rWORD7,rWORD8
772         bne     cr6,L(duLcr6)
773         srd     rA,rWORD2,rSHR
774         sld     rD,rWORD2,rSHL
775         or      rWORD2,rA,rB
776         addi    rSTR1,rSTR1,16
777         addi    rSTR2,rSTR2,16
778         cmpld   cr0,rWORD1,rWORD2
779         b       L(duLoop1)
780         .align  4
781 L(duP3x):
782         addi    rSTR1,rSTR1,16
783         addi    rSTR2,rSTR2,16
784         bne     cr1,L(duLcr1)
785         cmpld   cr5,rWORD7,rWORD8
786         bne     cr6,L(duLcr6)
787         sldi.   rN,rN,3
788         bne     cr5,L(duLcr5)
789         cmpld   cr7,rN,rSHR
790         beq     L(duZeroReturn)
791         li      rA,0
792         ble     cr7,L(dutrim)
793         ld      rWORD2,8(rSTR2)
794         srd     rA,rWORD2,rSHR
795         b       L(dutrim)
796
797 /* Count is a multiple of 32, remainder is 0 */
798         .align  4
799 L(duP4):
800         mtctr   rTMP
801         srd     rA,rWORD8,rSHR
802         ld      rWORD1,0(rSTR1)
803         sld     rD,rWORD8,rSHL
804         or      rWORD2,rA,rH
805 L(duP4e):
806         ld      rWORD3,8(rSTR1)
807         ld      rWORD4,8(rSTR2)
808         cmpld   cr0,rWORD1,rWORD2
809         srd     rC,rWORD4,rSHR
810         sld     rF,rWORD4,rSHL
811         or      rWORD4,rC,rD
812         ld      rWORD5,16(rSTR1)
813         ld      rWORD6,16(rSTR2)
814         cmpld   cr1,rWORD3,rWORD4
815         bne     cr0,L(duLcr0)
816         srd     rE,rWORD6,rSHR
817         sld     rH,rWORD6,rSHL
818         or      rWORD6,rE,rF
819         ldu     rWORD7,24(rSTR1)
820         ldu     rWORD8,24(rSTR2)
821         cmpld   cr6,rWORD5,rWORD6
822         bne     cr1,L(duLcr1)
823         srd     rG,rWORD8,rSHR
824         sld     rB,rWORD8,rSHL
825         or      rWORD8,rG,rH
826         cmpld   cr5,rWORD7,rWORD8
827         bdz     L(du24)         /* Adjust CTR as we start with +4 */
828 /* This is the primary loop */
829         .align  4
830 L(duLoop):
831         ld      rWORD1,8(rSTR1)
832         ld      rWORD2,8(rSTR2)
833         cmpld   cr1,rWORD3,rWORD4
834         bne     cr6,L(duLcr6)
835         srd     rA,rWORD2,rSHR
836         sld     rD,rWORD2,rSHL
837         or      rWORD2,rA,rB
838 L(duLoop1):
839         ld      rWORD3,16(rSTR1)
840         ld      rWORD4,16(rSTR2)
841         cmpld   cr6,rWORD5,rWORD6
842         bne     cr5,L(duLcr5)
843         srd     rC,rWORD4,rSHR
844         sld     rF,rWORD4,rSHL
845         or      rWORD4,rC,rD
846 L(duLoop2):
847         ld      rWORD5,24(rSTR1)
848         ld      rWORD6,24(rSTR2)
849         cmpld   cr5,rWORD7,rWORD8
850         bne     cr0,L(duLcr0)
851         srd     rE,rWORD6,rSHR
852         sld     rH,rWORD6,rSHL
853         or      rWORD6,rE,rF
854 L(duLoop3):
855         ldu     rWORD7,32(rSTR1)
856         ldu     rWORD8,32(rSTR2)
857         cmpld   cr0,rWORD1,rWORD2
858         bne-    cr1,L(duLcr1)
859         srd     rG,rWORD8,rSHR
860         sld     rB,rWORD8,rSHL
861         or      rWORD8,rG,rH
862         bdnz    L(duLoop)
863
864 L(duL4):
865         bne     cr1,L(duLcr1)
866         cmpld   cr1,rWORD3,rWORD4
867         bne     cr6,L(duLcr6)
868         cmpld   cr6,rWORD5,rWORD6
869         bne     cr5,L(duLcr5)
870         cmpld   cr5,rWORD7,rWORD8
871 L(du44):
872         bne     cr0,L(duLcr0)
873 L(du34):
874         bne     cr1,L(duLcr1)
875 L(du24):
876         bne     cr6,L(duLcr6)
877 L(du14):
878         sldi.   rN,rN,3
879         bne     cr5,L(duLcr5)
880 /* At this point we have a remainder of 1 to 7 bytes to compare.  We use
881    shift right double to elliminate bits beyond the compare length.
882    This allows the use of double word subtract to compute the final
883    result.
884
885    However it may not be safe to load rWORD2 which may be beyond the
886    string length. So we compare the bit length of the remainder to
887    the right shift count (rSHR). If the bit count is less than or equal
888    we do not need to load rWORD2 (all significant bits are already in
889    rB).  */
890         cmpld   cr7,rN,rSHR
891         beq     L(duZeroReturn)
892         li      rA,0
893         ble     cr7,L(dutrim)
894         ld      rWORD2,8(rSTR2)
895         srd     rA,rWORD2,rSHR
896         .align  4
897 L(dutrim):
898         ld      rWORD1,8(rSTR1)
899         ld      rWORD8,-8(r1)
900         subfic  rN,rN,64        /* Shift count is 64 - (rN * 8).  */
901         or      rWORD2,rA,rB
902         ld      rWORD7,-16(r1)
903         ld      r29,-24(r1)
904         srd     rWORD1,rWORD1,rN
905         srd     rWORD2,rWORD2,rN
906         ld      r28,-32(r1)
907         ld      r27,-40(r1)
908         li      rRTN,0
909         cmpld   cr0,rWORD1,rWORD2
910         ld      r26,-48(r1)
911         ld      r25,-56(r1)
912         beq     cr0,L(dureturn24)
913         li      rRTN,1
914         ld      r24,-64(r1)
915         bgtlr   cr0
916         li      rRTN,-1
917         blr
918         .align  4
919 L(duLcr0):
920         ld      rWORD8,-8(r1)
921         ld      rWORD7,-16(r1)
922         li      rRTN,1
923         bgt     cr0,L(dureturn29)
924         ld      r29,-24(r1)
925         ld      r28,-32(r1)
926         li      rRTN,-1
927         b       L(dureturn27)
928         .align  4
929 L(duLcr1):
930         ld      rWORD8,-8(r1)
931         ld      rWORD7,-16(r1)
932         li      rRTN,1
933         bgt     cr1,L(dureturn29)
934         ld      r29,-24(r1)
935         ld      r28,-32(r1)
936         li      rRTN,-1
937         b       L(dureturn27)
938         .align  4
939 L(duLcr6):
940         ld      rWORD8,-8(r1)
941         ld      rWORD7,-16(r1)
942         li      rRTN,1
943         bgt     cr6,L(dureturn29)
944         ld      r29,-24(r1)
945         ld      r28,-32(r1)
946         li      rRTN,-1
947         b       L(dureturn27)
948         .align  4
949 L(duLcr5):
950         ld      rWORD8,-8(r1)
951         ld      rWORD7,-16(r1)
952         li      rRTN,1
953         bgt     cr5,L(dureturn29)
954         ld      r29,-24(r1)
955         ld      r28,-32(r1)
956         li      rRTN,-1
957         b       L(dureturn27)
958         .align  3
959 L(duZeroReturn):
960         li      rRTN,0
961         .align  4
962 L(dureturn):
963         ld      rWORD8,-8(r1)
964         ld      rWORD7,-16(r1)
965 L(dureturn29):
966         ld      r29,-24(r1)
967         ld      r28,-32(r1)
968 L(dureturn27):
969         ld      r27,-40(r1)
970 L(dureturn26):
971         ld      r26,-48(r1)
972 L(dureturn25):
973         ld      r25,-56(r1)
974 L(dureturn24):
975         ld      r24,-64(r1)
976         blr
977 L(duzeroLength):
978         li      rRTN,0
979         blr
980
981 END (BP_SYM (memcmp))
982 libc_hidden_builtin_def (memcmp)
983 weak_alias (memcmp,bcmp)