1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "asm_support_x86_64.S"
18
19#define MEMCMP  __memcmp16
20
21/*
22 * Half of Silvermont L1 Data Cache size
23 *(see original file cache.h in bionic/libc/arch-x86_64/).
24 * This value is used for specific optimization on big lengths.
25 */
26#define DATA_CACHE_SIZE_HALF    (12*1024)
27
28#ifndef L
29# define L(label)    .L##label
30#endif
31
32#ifndef ALIGN
33# define ALIGN(n)    .p2align n
34#endif
35
36#define JMPTBL(I, B)    (I - B)
37
38#define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE)        \
39  lea        TABLE(%rip), %r11;                \
40  movslq    (%r11, INDEX, SCALE), %rcx;            \
41  add        %r11, %rcx;                    \
42  jmp        *%rcx;                        \
43  ud2
44
45DEFINE_FUNCTION MEMCMP
46    pxor      %xmm0, %xmm0
47    shl       $1, %rdx
48    cmp       $79, %rdx
49    ja        L(79bytesormore)
50    add       %rdx, %rsi
51    add       %rdx, %rdi
52    BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 2)
53
54    ALIGN (4)
55L(79bytesormore):
56    movdqu    (%rsi), %xmm1
57    movdqu    (%rdi), %xmm2
58    pxor      %xmm1, %xmm2
59    ptest     %xmm2, %xmm0
60    jnc       L(16bytesin256)
61    mov       %rsi, %rcx
62    and       $-16, %rsi
63    add       $16, %rsi
64    sub       %rsi, %rcx
65
66    sub       %rcx, %rdi
67    add       %rcx, %rdx
68    test      $0xf, %rdi
69    jz        L(2aligned)
70
71    cmp       $128, %rdx
72    ja        L(128bytesormore)
73L(less128bytes):
74    sub       $64, %rdx
75
76    movdqu    (%rdi), %xmm2
77    pxor      (%rsi), %xmm2
78    ptest     %xmm2, %xmm0
79    jnc       L(16bytesin256)
80
81    movdqu    16(%rdi), %xmm2
82    pxor      16(%rsi), %xmm2
83    ptest     %xmm2, %xmm0
84    jnc       L(32bytesin256)
85
86    movdqu    32(%rdi), %xmm2
87    pxor      32(%rsi), %xmm2
88    ptest     %xmm2, %xmm0
89    jnc       L(48bytesin256)
90
91    movdqu    48(%rdi), %xmm2
92    pxor      48(%rsi), %xmm2
93    ptest     %xmm2, %xmm0
94    jnc       L(64bytesin256)
95    cmp       $32, %rdx
96    jb        L(less32bytesin64)
97
98    movdqu    64(%rdi), %xmm2
99    pxor      64(%rsi), %xmm2
100    ptest     %xmm2, %xmm0
101    jnc       L(80bytesin256)
102
103    movdqu    80(%rdi), %xmm2
104    pxor      80(%rsi), %xmm2
105    ptest     %xmm2, %xmm0
106    jnc       L(96bytesin256)
107    sub       $32, %rdx
108    add       $32, %rdi
109    add       $32, %rsi
110L(less32bytesin64):
111    add       $64, %rdi
112    add       $64, %rsi
113    add       %rdx, %rsi
114    add       %rdx, %rdi
115    BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 2)
116
117L(128bytesormore):
118    cmp       $512, %rdx
119    ja        L(512bytesormore)
120    cmp       $256, %rdx
121    ja        L(less512bytes)
122L(less256bytes):
123    sub       $128, %rdx
124
125    movdqu    (%rdi), %xmm2
126    pxor      (%rsi), %xmm2
127    ptest     %xmm2, %xmm0
128    jnc       L(16bytesin256)
129
130    movdqu    16(%rdi), %xmm2
131    pxor      16(%rsi), %xmm2
132    ptest     %xmm2, %xmm0
133    jnc       L(32bytesin256)
134
135    movdqu    32(%rdi), %xmm2
136    pxor      32(%rsi), %xmm2
137    ptest     %xmm2, %xmm0
138    jnc       L(48bytesin256)
139
140    movdqu    48(%rdi), %xmm2
141    pxor      48(%rsi), %xmm2
142    ptest     %xmm2, %xmm0
143    jnc       L(64bytesin256)
144
145    movdqu    64(%rdi), %xmm2
146    pxor      64(%rsi), %xmm2
147    ptest     %xmm2, %xmm0
148    jnc       L(80bytesin256)
149
150    movdqu    80(%rdi), %xmm2
151    pxor      80(%rsi), %xmm2
152    ptest     %xmm2, %xmm0
153    jnc       L(96bytesin256)
154
155    movdqu    96(%rdi), %xmm2
156    pxor      96(%rsi), %xmm2
157    ptest     %xmm2, %xmm0
158    jnc       L(112bytesin256)
159
160    movdqu    112(%rdi), %xmm2
161    pxor      112(%rsi), %xmm2
162    ptest     %xmm2, %xmm0
163    jnc       L(128bytesin256)
164
165    add       $128, %rsi
166    add       $128, %rdi
167
168    cmp       $64, %rdx
169    jae       L(less128bytes)
170
171    cmp       $32, %rdx
172    jb        L(less32bytesin128)
173
174    movdqu    (%rdi), %xmm2
175    pxor      (%rsi), %xmm2
176    ptest     %xmm2, %xmm0
177    jnc       L(16bytesin256)
178
179    movdqu    16(%rdi), %xmm2
180    pxor      16(%rsi), %xmm2
181    ptest     %xmm2, %xmm0
182    jnc       L(32bytesin256)
183    sub       $32, %rdx
184    add       $32, %rdi
185    add       $32, %rsi
186L(less32bytesin128):
187    add       %rdx, %rsi
188    add       %rdx, %rdi
189    BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 2)
190
191L(less512bytes):
192    sub       $256, %rdx
193    movdqu    (%rdi), %xmm2
194    pxor      (%rsi), %xmm2
195    ptest     %xmm2, %xmm0
196    jnc       L(16bytesin256)
197
198    movdqu    16(%rdi), %xmm2
199    pxor      16(%rsi), %xmm2
200    ptest     %xmm2, %xmm0
201    jnc       L(32bytesin256)
202
203    movdqu    32(%rdi), %xmm2
204    pxor      32(%rsi), %xmm2
205    ptest     %xmm2, %xmm0
206    jnc       L(48bytesin256)
207
208    movdqu    48(%rdi), %xmm2
209    pxor      48(%rsi), %xmm2
210    ptest     %xmm2, %xmm0
211    jnc       L(64bytesin256)
212
213    movdqu    64(%rdi), %xmm2
214    pxor      64(%rsi), %xmm2
215    ptest     %xmm2, %xmm0
216    jnc       L(80bytesin256)
217
218    movdqu    80(%rdi), %xmm2
219    pxor      80(%rsi), %xmm2
220    ptest     %xmm2, %xmm0
221    jnc       L(96bytesin256)
222
223    movdqu    96(%rdi), %xmm2
224    pxor      96(%rsi), %xmm2
225    ptest     %xmm2, %xmm0
226    jnc       L(112bytesin256)
227
228    movdqu    112(%rdi), %xmm2
229    pxor      112(%rsi), %xmm2
230    ptest     %xmm2, %xmm0
231    jnc       L(128bytesin256)
232
233    movdqu    128(%rdi), %xmm2
234    pxor      128(%rsi), %xmm2
235    ptest     %xmm2, %xmm0
236    jnc       L(144bytesin256)
237
238    movdqu    144(%rdi), %xmm2
239    pxor      144(%rsi), %xmm2
240    ptest     %xmm2, %xmm0
241    jnc       L(160bytesin256)
242
243    movdqu    160(%rdi), %xmm2
244    pxor      160(%rsi), %xmm2
245    ptest     %xmm2, %xmm0
246    jnc       L(176bytesin256)
247
248    movdqu    176(%rdi), %xmm2
249    pxor      176(%rsi), %xmm2
250    ptest     %xmm2, %xmm0
251    jnc       L(192bytesin256)
252
253    movdqu    192(%rdi), %xmm2
254    pxor      192(%rsi), %xmm2
255    ptest     %xmm2, %xmm0
256    jnc       L(208bytesin256)
257
258    movdqu    208(%rdi), %xmm2
259    pxor      208(%rsi), %xmm2
260    ptest     %xmm2, %xmm0
261    jnc       L(224bytesin256)
262
263    movdqu    224(%rdi), %xmm2
264    pxor      224(%rsi), %xmm2
265    ptest     %xmm2, %xmm0
266    jnc       L(240bytesin256)
267
268    movdqu    240(%rdi), %xmm2
269    pxor      240(%rsi), %xmm2
270    ptest     %xmm2, %xmm0
271    jnc       L(256bytesin256)
272
273    add       $256, %rsi
274    add       $256, %rdi
275
276    cmp       $128, %rdx
277    jae       L(less256bytes)
278
279    cmp       $64, %rdx
280    jae       L(less128bytes)
281
282    cmp       $32, %rdx
283    jb        L(less32bytesin256)
284
285    movdqu    (%rdi), %xmm2
286    pxor      (%rsi), %xmm2
287    ptest     %xmm2, %xmm0
288    jnc       L(16bytesin256)
289
290    movdqu    16(%rdi), %xmm2
291    pxor      16(%rsi), %xmm2
292    ptest     %xmm2, %xmm0
293    jnc       L(32bytesin256)
294    sub       $32, %rdx
295    add       $32, %rdi
296    add       $32, %rsi
297L(less32bytesin256):
298    add       %rdx, %rsi
299    add       %rdx, %rdi
300    BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 2)
301
302    ALIGN (4)
303L(512bytesormore):
304#ifdef DATA_CACHE_SIZE_HALF
305    mov       $DATA_CACHE_SIZE_HALF, %r8
306#else
307    mov       __x86_64_data_cache_size_half(%rip), %r8
308#endif
309    mov       %r8, %r9
310    shr       $1, %r8
311    add       %r9, %r8
312    cmp       %r8, %rdx
313    ja        L(L2_L3_cache_unaglined)
314    sub       $64, %rdx
315    ALIGN (4)
316L(64bytesormore_loop):
317    movdqu    (%rdi), %xmm2
318    pxor      (%rsi), %xmm2
319    movdqa    %xmm2, %xmm1
320
321    movdqu    16(%rdi), %xmm3
322    pxor      16(%rsi), %xmm3
323    por       %xmm3, %xmm1
324
325    movdqu    32(%rdi), %xmm4
326    pxor      32(%rsi), %xmm4
327    por       %xmm4, %xmm1
328
329    movdqu    48(%rdi), %xmm5
330    pxor      48(%rsi), %xmm5
331    por       %xmm5, %xmm1
332
333    ptest     %xmm1, %xmm0
334    jnc       L(64bytesormore_loop_end)
335    add       $64, %rsi
336    add       $64, %rdi
337    sub       $64, %rdx
338    jae       L(64bytesormore_loop)
339
340    add       $64, %rdx
341    add       %rdx, %rsi
342    add       %rdx, %rdi
343    BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 2)
344
345L(L2_L3_cache_unaglined):
346    sub       $64, %rdx
347    ALIGN (4)
348L(L2_L3_unaligned_128bytes_loop):
349    prefetchnta 0x1c0(%rdi)
350    prefetchnta 0x1c0(%rsi)
351    movdqu    (%rdi), %xmm2
352    pxor      (%rsi), %xmm2
353    movdqa    %xmm2, %xmm1
354
355    movdqu    16(%rdi), %xmm3
356    pxor      16(%rsi), %xmm3
357    por       %xmm3, %xmm1
358
359    movdqu    32(%rdi), %xmm4
360    pxor      32(%rsi), %xmm4
361    por       %xmm4, %xmm1
362
363    movdqu    48(%rdi), %xmm5
364    pxor      48(%rsi), %xmm5
365    por       %xmm5, %xmm1
366
367    ptest     %xmm1, %xmm0
368    jnc       L(64bytesormore_loop_end)
369    add       $64, %rsi
370    add       $64, %rdi
371    sub       $64, %rdx
372    jae       L(L2_L3_unaligned_128bytes_loop)
373
374    add       $64, %rdx
375    add       %rdx, %rsi
376    add       %rdx, %rdi
377    BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 2)
378
379/*
380 * This case is for machines which are sensitive for unaligned instructions.
381 */
382    ALIGN (4)
383L(2aligned):
384    cmp       $128, %rdx
385    ja        L(128bytesormorein2aligned)
386L(less128bytesin2aligned):
387    sub       $64, %rdx
388
389    movdqa    (%rdi), %xmm2
390    pxor      (%rsi), %xmm2
391    ptest     %xmm2, %xmm0
392    jnc       L(16bytesin256)
393
394    movdqa    16(%rdi), %xmm2
395    pxor      16(%rsi), %xmm2
396    ptest     %xmm2, %xmm0
397    jnc       L(32bytesin256)
398
399    movdqa    32(%rdi), %xmm2
400    pxor      32(%rsi), %xmm2
401    ptest     %xmm2, %xmm0
402    jnc       L(48bytesin256)
403
404    movdqa    48(%rdi), %xmm2
405    pxor      48(%rsi), %xmm2
406    ptest     %xmm2, %xmm0
407    jnc       L(64bytesin256)
408    cmp       $32, %rdx
409    jb        L(less32bytesin64in2alinged)
410
411    movdqa    64(%rdi), %xmm2
412    pxor      64(%rsi), %xmm2
413    ptest     %xmm2, %xmm0
414    jnc       L(80bytesin256)
415
416    movdqa    80(%rdi), %xmm2
417    pxor      80(%rsi), %xmm2
418    ptest     %xmm2, %xmm0
419    jnc       L(96bytesin256)
420    sub       $32, %rdx
421    add       $32, %rdi
422    add       $32, %rsi
423L(less32bytesin64in2alinged):
424    add       $64, %rdi
425    add       $64, %rsi
426    add       %rdx, %rsi
427    add       %rdx, %rdi
428    BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 2)
429
430    ALIGN (4)
431L(128bytesormorein2aligned):
432    cmp       $512, %rdx
433    ja        L(512bytesormorein2aligned)
434    cmp       $256, %rdx
435    ja        L(256bytesormorein2aligned)
436L(less256bytesin2alinged):
437    sub       $128, %rdx
438
439    movdqa    (%rdi), %xmm2
440    pxor      (%rsi), %xmm2
441    ptest     %xmm2, %xmm0
442    jnc       L(16bytesin256)
443
444    movdqa    16(%rdi), %xmm2
445    pxor      16(%rsi), %xmm2
446    ptest     %xmm2, %xmm0
447    jnc       L(32bytesin256)
448
449    movdqa    32(%rdi), %xmm2
450    pxor      32(%rsi), %xmm2
451    ptest     %xmm2, %xmm0
452    jnc       L(48bytesin256)
453
454    movdqa    48(%rdi), %xmm2
455    pxor      48(%rsi), %xmm2
456    ptest     %xmm2, %xmm0
457    jnc       L(64bytesin256)
458
459    movdqa    64(%rdi), %xmm2
460    pxor      64(%rsi), %xmm2
461    ptest     %xmm2, %xmm0
462    jnc       L(80bytesin256)
463
464    movdqa    80(%rdi), %xmm2
465    pxor      80(%rsi), %xmm2
466    ptest     %xmm2, %xmm0
467    jnc       L(96bytesin256)
468
469    movdqa    96(%rdi), %xmm2
470    pxor      96(%rsi), %xmm2
471    ptest     %xmm2, %xmm0
472    jnc       L(112bytesin256)
473
474    movdqa    112(%rdi), %xmm2
475    pxor      112(%rsi), %xmm2
476    ptest     %xmm2, %xmm0
477    jnc       L(128bytesin256)
478
479    add       $128, %rsi
480    add       $128, %rdi
481
482    cmp       $64, %rdx
483    jae       L(less128bytesin2aligned)
484
485    cmp       $32, %rdx
486    jb        L(less32bytesin128in2aligned)
487
488    movdqu    (%rdi), %xmm2
489    pxor      (%rsi), %xmm2
490    ptest     %xmm2, %xmm0
491    jnc       L(16bytesin256)
492
493    movdqu    16(%rdi), %xmm2
494    pxor      16(%rsi), %xmm2
495    ptest     %xmm2, %xmm0
496    jnc       L(32bytesin256)
497    sub       $32, %rdx
498    add       $32, %rdi
499    add       $32, %rsi
500L(less32bytesin128in2aligned):
501    add       %rdx, %rsi
502    add       %rdx, %rdi
503    BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 2)
504
505    ALIGN (4)
506L(256bytesormorein2aligned):
507
508    sub       $256, %rdx
509    movdqa    (%rdi), %xmm2
510    pxor      (%rsi), %xmm2
511    ptest     %xmm2, %xmm0
512    jnc       L(16bytesin256)
513
514    movdqa    16(%rdi), %xmm2
515    pxor      16(%rsi), %xmm2
516    ptest     %xmm2, %xmm0
517    jnc       L(32bytesin256)
518
519    movdqa    32(%rdi), %xmm2
520    pxor      32(%rsi), %xmm2
521    ptest     %xmm2, %xmm0
522    jnc       L(48bytesin256)
523
524    movdqa    48(%rdi), %xmm2
525    pxor      48(%rsi), %xmm2
526    ptest     %xmm2, %xmm0
527    jnc       L(64bytesin256)
528
529    movdqa    64(%rdi), %xmm2
530    pxor      64(%rsi), %xmm2
531    ptest     %xmm2, %xmm0
532    jnc       L(80bytesin256)
533
534    movdqa    80(%rdi), %xmm2
535    pxor      80(%rsi), %xmm2
536    ptest     %xmm2, %xmm0
537    jnc       L(96bytesin256)
538
539    movdqa    96(%rdi), %xmm2
540    pxor      96(%rsi), %xmm2
541    ptest     %xmm2, %xmm0
542    jnc       L(112bytesin256)
543
544    movdqa    112(%rdi), %xmm2
545    pxor      112(%rsi), %xmm2
546    ptest     %xmm2, %xmm0
547    jnc       L(128bytesin256)
548
549    movdqa    128(%rdi), %xmm2
550    pxor      128(%rsi), %xmm2
551    ptest     %xmm2, %xmm0
552    jnc       L(144bytesin256)
553
554    movdqa    144(%rdi), %xmm2
555    pxor      144(%rsi), %xmm2
556    ptest     %xmm2, %xmm0
557    jnc       L(160bytesin256)
558
559    movdqa    160(%rdi), %xmm2
560    pxor      160(%rsi), %xmm2
561    ptest     %xmm2, %xmm0
562    jnc       L(176bytesin256)
563
564    movdqa    176(%rdi), %xmm2
565    pxor      176(%rsi), %xmm2
566    ptest     %xmm2, %xmm0
567    jnc       L(192bytesin256)
568
569    movdqa    192(%rdi), %xmm2
570    pxor      192(%rsi), %xmm2
571    ptest     %xmm2, %xmm0
572    jnc       L(208bytesin256)
573
574    movdqa    208(%rdi), %xmm2
575    pxor      208(%rsi), %xmm2
576    ptest     %xmm2, %xmm0
577    jnc       L(224bytesin256)
578
579    movdqa    224(%rdi), %xmm2
580    pxor      224(%rsi), %xmm2
581    ptest     %xmm2, %xmm0
582    jnc       L(240bytesin256)
583
584    movdqa    240(%rdi), %xmm2
585    pxor      240(%rsi), %xmm2
586    ptest     %xmm2, %xmm0
587    jnc       L(256bytesin256)
588
589    add       $256, %rsi
590    add       $256, %rdi
591
592    cmp       $128, %rdx
593    jae       L(less256bytesin2alinged)
594
595    cmp       $64, %rdx
596    jae       L(less128bytesin2aligned)
597
598    cmp       $32, %rdx
599    jb        L(less32bytesin256in2alinged)
600
601    movdqa    (%rdi), %xmm2
602    pxor      (%rsi), %xmm2
603    ptest     %xmm2, %xmm0
604    jnc       L(16bytesin256)
605
606    movdqa    16(%rdi), %xmm2
607    pxor      16(%rsi), %xmm2
608    ptest     %xmm2, %xmm0
609    jnc       L(32bytesin256)
610    sub       $32, %rdx
611    add       $32, %rdi
612    add       $32, %rsi
613L(less32bytesin256in2alinged):
614    add       %rdx, %rsi
615    add       %rdx, %rdi
616    BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 2)
617
618    ALIGN (4)
619L(512bytesormorein2aligned):
620#ifdef DATA_CACHE_SIZE_HALF
621    mov       $DATA_CACHE_SIZE_HALF, %r8
622#else
623    mov       __x86_64_data_cache_size_half(%rip), %r8
624#endif
625    mov       %r8, %r9
626    shr       $1, %r8
627    add       %r9, %r8
628    cmp       %r8, %rdx
629    ja        L(L2_L3_cache_aglined)
630
631    sub       $64, %rdx
632    ALIGN (4)
633L(64bytesormore_loopin2aligned):
634    movdqa    (%rdi), %xmm2
635    pxor      (%rsi), %xmm2
636    movdqa    %xmm2, %xmm1
637
638    movdqa    16(%rdi), %xmm3
639    pxor      16(%rsi), %xmm3
640    por       %xmm3, %xmm1
641
642    movdqa    32(%rdi), %xmm4
643    pxor      32(%rsi), %xmm4
644    por       %xmm4, %xmm1
645
646    movdqa    48(%rdi), %xmm5
647    pxor      48(%rsi), %xmm5
648    por       %xmm5, %xmm1
649
650    ptest     %xmm1, %xmm0
651    jnc       L(64bytesormore_loop_end)
652    add       $64, %rsi
653    add       $64, %rdi
654    sub       $64, %rdx
655    jae       L(64bytesormore_loopin2aligned)
656
657    add       $64, %rdx
658    add       %rdx, %rsi
659    add       %rdx, %rdi
660    BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 2)
661L(L2_L3_cache_aglined):
662    sub       $64, %rdx
663    ALIGN (4)
664L(L2_L3_aligned_128bytes_loop):
665    prefetchnta 0x1c0(%rdi)
666    prefetchnta 0x1c0(%rsi)
667    movdqa    (%rdi), %xmm2
668    pxor      (%rsi), %xmm2
669    movdqa    %xmm2, %xmm1
670
671    movdqa    16(%rdi), %xmm3
672    pxor      16(%rsi), %xmm3
673    por       %xmm3, %xmm1
674
675    movdqa    32(%rdi), %xmm4
676    pxor      32(%rsi), %xmm4
677    por       %xmm4, %xmm1
678
679    movdqa    48(%rdi), %xmm5
680    pxor      48(%rsi), %xmm5
681    por       %xmm5, %xmm1
682
683    ptest     %xmm1, %xmm0
684    jnc       L(64bytesormore_loop_end)
685    add       $64, %rsi
686    add       $64, %rdi
687    sub       $64, %rdx
688    jae    L(L2_L3_aligned_128bytes_loop)
689
690    add       $64, %rdx
691    add       %rdx, %rsi
692    add       %rdx, %rdi
693    BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %rdx, 2)
694
695
696    ALIGN (4)
697L(64bytesormore_loop_end):
698    add       $16, %rdi
699    add       $16, %rsi
700    ptest     %xmm2, %xmm0
701    jnc       L(16bytes)
702
703    add       $16, %rdi
704    add       $16, %rsi
705    ptest     %xmm3, %xmm0
706    jnc       L(16bytes)
707
708    add       $16, %rdi
709    add       $16, %rsi
710    ptest     %xmm4, %xmm0
711    jnc       L(16bytes)
712
713    add       $16, %rdi
714    add       $16, %rsi
715    jmp       L(16bytes)
716
717L(256bytesin256):
718    add       $256, %rdi
719    add       $256, %rsi
720    jmp       L(16bytes)
721L(240bytesin256):
722    add       $240, %rdi
723    add       $240, %rsi
724    jmp       L(16bytes)
725L(224bytesin256):
726    add       $224, %rdi
727    add       $224, %rsi
728    jmp       L(16bytes)
729L(208bytesin256):
730    add       $208, %rdi
731    add       $208, %rsi
732    jmp       L(16bytes)
733L(192bytesin256):
734    add       $192, %rdi
735    add       $192, %rsi
736    jmp       L(16bytes)
737L(176bytesin256):
738    add       $176, %rdi
739    add       $176, %rsi
740    jmp       L(16bytes)
741L(160bytesin256):
742    add       $160, %rdi
743    add       $160, %rsi
744    jmp       L(16bytes)
745L(144bytesin256):
746    add       $144, %rdi
747    add       $144, %rsi
748    jmp       L(16bytes)
749L(128bytesin256):
750    add       $128, %rdi
751    add       $128, %rsi
752    jmp       L(16bytes)
753L(112bytesin256):
754    add       $112, %rdi
755    add       $112, %rsi
756    jmp       L(16bytes)
757L(96bytesin256):
758    add       $96, %rdi
759    add       $96, %rsi
760    jmp       L(16bytes)
761L(80bytesin256):
762    add       $80, %rdi
763    add       $80, %rsi
764    jmp       L(16bytes)
765L(64bytesin256):
766    add       $64, %rdi
767    add       $64, %rsi
768    jmp       L(16bytes)
769L(48bytesin256):
770    add       $16, %rdi
771    add       $16, %rsi
772L(32bytesin256):
773    add       $16, %rdi
774    add       $16, %rsi
775L(16bytesin256):
776    add       $16, %rdi
777    add       $16, %rsi
778L(16bytes):
779    mov       -16(%rdi), %rax
780    mov       -16(%rsi), %rcx
781    cmp       %rax, %rcx
782    jne       L(diffin8bytes)
783L(8bytes):
784    mov       -8(%rdi), %rax
785    mov       -8(%rsi), %rcx
786    cmp       %rax, %rcx
787    jne       L(diffin8bytes)
788    xor       %eax, %eax
789    ret
790
791    ALIGN (4)
792L(12bytes):
793    mov       -12(%rdi), %rax
794    mov       -12(%rsi), %rcx
795    cmp       %rax, %rcx
796    jne       L(diffin8bytes)
797L(4bytes):
798    mov       -4(%rsi), %ecx
799    mov       -4(%rdi), %eax
800    cmp       %eax, %ecx
801    jne       L(diffin4bytes)
802L(0bytes):
803    xor       %eax, %eax
804    ret
805
806    ALIGN (4)
807L(66bytes):
808    movdqu    -66(%rdi), %xmm1
809    movdqu    -66(%rsi), %xmm2
810    mov       $-66, %dl
811    pxor      %xmm1, %xmm2
812    ptest     %xmm2, %xmm0
813    jnc       L(less16bytes)
814L(50bytes):
815    movdqu    -50(%rdi), %xmm1
816    movdqu    -50(%rsi), %xmm2
817    mov       $-50, %dl
818    pxor      %xmm1, %xmm2
819    ptest     %xmm2, %xmm0
820    jnc       L(less16bytes)
821L(34bytes):
822    movdqu    -34(%rdi), %xmm1
823    movdqu    -34(%rsi), %xmm2
824    mov       $-34, %dl
825    pxor      %xmm1, %xmm2
826    ptest     %xmm2, %xmm0
827    jnc       L(less16bytes)
828L(18bytes):
829    mov       -18(%rdi), %rax
830    mov       -18(%rsi), %rcx
831    cmp       %rax, %rcx
832    jne       L(diffin8bytes)
833L(10bytes):
834    mov       -10(%rdi), %rax
835    mov       -10(%rsi), %rcx
836    cmp       %rax, %rcx
837    jne       L(diffin8bytes)
838    movzwl    -2(%rdi), %eax
839    movzwl    -2(%rsi), %ecx
840    cmp       %cl, %al
841    jne       L(end)
842    and       $0xffff, %eax
843    and       $0xffff, %ecx
844    sub       %ecx, %eax
845    ret
846
847    ALIGN (4)
848L(14bytes):
849    mov       -14(%rdi), %rax
850    mov       -14(%rsi), %rcx
851    cmp       %rax, %rcx
852    jne       L(diffin8bytes)
853    mov       -8(%rdi), %rax
854    mov       -8(%rsi), %rcx
855    cmp       %rax, %rcx
856    jne       L(diffin8bytes)
857    xor       %eax, %eax
858    ret
859
860    ALIGN (4)
861L(6bytes):
862    mov       -6(%rdi), %eax
863    mov       -6(%rsi), %ecx
864    cmp       %eax, %ecx
865    jne       L(diffin4bytes)
866L(2bytes):
867    movzwl    -2(%rsi), %ecx
868    movzwl    -2(%rdi), %eax
869    cmp       %cl, %al
870    jne       L(end)
871    and       $0xffff, %eax
872    and       $0xffff, %ecx
873    sub       %ecx, %eax
874    ret
875
876    ALIGN (4)
877L(68bytes):
878    movdqu    -68(%rdi), %xmm2
879    movdqu    -68(%rsi), %xmm1
880    mov       $-68, %dl
881    pxor      %xmm1, %xmm2
882    ptest     %xmm2, %xmm0
883    jnc       L(less16bytes)
884L(52bytes):
885    movdqu    -52(%rdi), %xmm2
886    movdqu    -52(%rsi), %xmm1
887    mov       $-52, %dl
888    pxor      %xmm1, %xmm2
889    ptest     %xmm2, %xmm0
890    jnc       L(less16bytes)
891L(36bytes):
892    movdqu    -36(%rdi), %xmm2
893    movdqu    -36(%rsi), %xmm1
894    mov       $-36, %dl
895    pxor      %xmm1, %xmm2
896    ptest     %xmm2, %xmm0
897    jnc       L(less16bytes)
898L(20bytes):
899    movdqu    -20(%rdi), %xmm2
900    movdqu    -20(%rsi), %xmm1
901    mov       $-20, %dl
902    pxor      %xmm1, %xmm2
903    ptest     %xmm2, %xmm0
904    jnc       L(less16bytes)
905    mov       -4(%rdi), %eax
906    mov       -4(%rsi), %ecx
907    cmp       %eax, %ecx
908    jne       L(diffin4bytes)
909    xor       %eax, %eax
910    ret
911
912    ALIGN (4)
913L(70bytes):
914    movdqu    -70(%rsi), %xmm1
915    movdqu    -70(%rdi), %xmm2
916    mov       $-70, %dl
917    pxor      %xmm1, %xmm2
918    ptest     %xmm2, %xmm0
919    jnc       L(less16bytes)
920L(54bytes):
921    movdqu    -54(%rsi), %xmm1
922    movdqu    -54(%rdi), %xmm2
923    mov       $-54, %dl
924    pxor      %xmm1, %xmm2
925    ptest     %xmm2, %xmm0
926    jnc       L(less16bytes)
927L(38bytes):
928    movdqu    -38(%rsi), %xmm1
929    movdqu    -38(%rdi), %xmm2
930    mov       $-38, %dl
931    pxor      %xmm1, %xmm2
932    ptest     %xmm2, %xmm0
933    jnc       L(less16bytes)
934L(22bytes):
935    movdqu    -22(%rsi), %xmm1
936    movdqu    -22(%rdi), %xmm2
937    mov       $-22, %dl
938    pxor      %xmm1, %xmm2
939    ptest     %xmm2, %xmm0
940    jnc       L(less16bytes)
941    mov       -8(%rdi), %rax
942    mov       -8(%rsi), %rcx
943    cmp       %rax, %rcx
944    jne       L(diffin8bytes)
945    xor       %eax, %eax
946    ret
947
948    ALIGN (4)
949L(72bytes):
950    movdqu    -72(%rsi), %xmm1
951    movdqu    -72(%rdi), %xmm2
952    mov       $-72, %dl
953    pxor      %xmm1, %xmm2
954    ptest     %xmm2, %xmm0
955    jnc       L(less16bytes)
956L(56bytes):
957    movdqu    -56(%rdi), %xmm2
958    movdqu    -56(%rsi), %xmm1
959    mov       $-56, %dl
960    pxor      %xmm1, %xmm2
961    ptest     %xmm2, %xmm0
962    jnc       L(less16bytes)
963L(40bytes):
964    movdqu    -40(%rdi), %xmm2
965    movdqu    -40(%rsi), %xmm1
966    mov       $-40, %dl
967    pxor      %xmm1, %xmm2
968    ptest     %xmm2, %xmm0
969    jnc       L(less16bytes)
970L(24bytes):
971    movdqu    -24(%rdi), %xmm2
972    movdqu    -24(%rsi), %xmm1
973    mov       $-24, %dl
974    pxor      %xmm1, %xmm2
975    ptest     %xmm2, %xmm0
976    jnc       L(less16bytes)
977    mov       -8(%rdi), %rax
978    mov       -8(%rsi), %rcx
979    cmp       %rax, %rcx
980    jne       L(diffin8bytes)
981    xor       %eax, %eax
982    ret
983
984    ALIGN (4)
985L(74bytes):
986    movdqu    -74(%rsi), %xmm1
987    movdqu    -74(%rdi), %xmm2
988    mov       $-74, %dl
989    pxor      %xmm1, %xmm2
990    ptest     %xmm2, %xmm0
991    jnc       L(less16bytes)
992L(58bytes):
993    movdqu    -58(%rdi), %xmm2
994    movdqu    -58(%rsi), %xmm1
995    mov       $-58, %dl
996    pxor      %xmm1, %xmm2
997    ptest     %xmm2, %xmm0
998    jnc       L(less16bytes)
999L(42bytes):
1000    movdqu    -42(%rdi), %xmm2
1001    movdqu    -42(%rsi), %xmm1
1002    mov       $-42, %dl
1003    pxor      %xmm1, %xmm2
1004    ptest     %xmm2, %xmm0
1005    jnc       L(less16bytes)
1006L(26bytes):
1007    movdqu    -26(%rdi), %xmm2
1008    movdqu    -26(%rsi), %xmm1
1009    mov       $-26, %dl
1010    pxor      %xmm1, %xmm2
1011    ptest     %xmm2, %xmm0
1012    jnc       L(less16bytes)
1013    mov       -10(%rdi), %rax
1014    mov       -10(%rsi), %rcx
1015    cmp       %rax, %rcx
1016    jne       L(diffin8bytes)
1017    movzwl    -2(%rdi), %eax
1018    movzwl    -2(%rsi), %ecx
1019    jmp       L(end)
1020
1021    ALIGN (4)
1022L(76bytes):
1023    movdqu    -76(%rsi), %xmm1
1024    movdqu    -76(%rdi), %xmm2
1025    mov       $-76, %dl
1026    pxor      %xmm1, %xmm2
1027    ptest     %xmm2, %xmm0
1028    jnc       L(less16bytes)
1029L(60bytes):
1030    movdqu    -60(%rdi), %xmm2
1031    movdqu    -60(%rsi), %xmm1
1032    mov       $-60, %dl
1033    pxor      %xmm1, %xmm2
1034    ptest     %xmm2, %xmm0
1035    jnc       L(less16bytes)
1036L(44bytes):
1037    movdqu    -44(%rdi), %xmm2
1038    movdqu    -44(%rsi), %xmm1
1039    mov       $-44, %dl
1040    pxor      %xmm1, %xmm2
1041    ptest     %xmm2, %xmm0
1042    jnc       L(less16bytes)
1043L(28bytes):
1044    movdqu    -28(%rdi), %xmm2
1045    movdqu    -28(%rsi), %xmm1
1046    mov       $-28, %dl
1047    pxor      %xmm1, %xmm2
1048    ptest     %xmm2, %xmm0
1049    jnc       L(less16bytes)
1050    mov       -12(%rdi), %rax
1051    mov       -12(%rsi), %rcx
1052    cmp       %rax, %rcx
1053    jne       L(diffin8bytes)
1054    mov       -4(%rdi), %eax
1055    mov       -4(%rsi), %ecx
1056    cmp       %eax, %ecx
1057    jne       L(diffin4bytes)
1058    xor       %eax, %eax
1059    ret
1060
1061    ALIGN (4)
1062L(78bytes):
1063    movdqu    -78(%rsi), %xmm1
1064    movdqu    -78(%rdi), %xmm2
1065    mov       $-78, %dl
1066    pxor      %xmm1, %xmm2
1067    ptest     %xmm2, %xmm0
1068    jnc       L(less16bytes)
1069L(62bytes):
1070    movdqu    -62(%rdi), %xmm2
1071    movdqu    -62(%rsi), %xmm1
1072    mov       $-62, %dl
1073    pxor      %xmm1, %xmm2
1074    ptest     %xmm2, %xmm0
1075    jnc       L(less16bytes)
1076L(46bytes):
1077    movdqu    -46(%rdi), %xmm2
1078    movdqu    -46(%rsi), %xmm1
1079    mov       $-46, %dl
1080    pxor      %xmm1, %xmm2
1081    ptest     %xmm2, %xmm0
1082    jnc       L(less16bytes)
1083L(30bytes):
1084    movdqu    -30(%rdi), %xmm2
1085    movdqu    -30(%rsi), %xmm1
1086    mov       $-30, %dl
1087    pxor      %xmm1, %xmm2
1088    ptest     %xmm2, %xmm0
1089    jnc       L(less16bytes)
1090    mov       -14(%rdi), %rax
1091    mov       -14(%rsi), %rcx
1092    cmp       %rax, %rcx
1093    jne       L(diffin8bytes)
1094    mov       -8(%rdi), %rax
1095    mov       -8(%rsi), %rcx
1096    cmp       %rax, %rcx
1097    jne       L(diffin8bytes)
1098    xor       %eax, %eax
1099    ret
1100
1101    ALIGN (4)
1102L(64bytes):
1103    movdqu    -64(%rdi), %xmm2
1104    movdqu    -64(%rsi), %xmm1
1105    mov       $-64, %dl
1106    pxor      %xmm1, %xmm2
1107    ptest     %xmm2, %xmm0
1108    jnc       L(less16bytes)
1109L(48bytes):
1110    movdqu    -48(%rdi), %xmm2
1111    movdqu    -48(%rsi), %xmm1
1112    mov       $-48, %dl
1113    pxor      %xmm1, %xmm2
1114    ptest     %xmm2, %xmm0
1115    jnc       L(less16bytes)
1116L(32bytes):
1117    movdqu    -32(%rdi), %xmm2
1118    movdqu    -32(%rsi), %xmm1
1119    mov       $-32, %dl
1120    pxor      %xmm1, %xmm2
1121    ptest     %xmm2, %xmm0
1122    jnc       L(less16bytes)
1123
1124    mov       -16(%rdi), %rax
1125    mov       -16(%rsi), %rcx
1126    cmp       %rax, %rcx
1127    jne       L(diffin8bytes)
1128
1129    mov       -8(%rdi), %rax
1130    mov       -8(%rsi), %rcx
1131    cmp       %rax, %rcx
1132    jne       L(diffin8bytes)
1133    xor       %eax, %eax
1134    ret
1135
1136/*
1137 * Aligned 8 bytes to avoid 2 branch "taken" in one 16 alinged code block.
1138 */
1139    ALIGN (3)
1140L(less16bytes):
1141    movsbq    %dl, %rdx
1142    mov       (%rsi, %rdx), %rcx
1143    mov       (%rdi, %rdx), %rax
1144    cmp       %rax, %rcx
1145    jne       L(diffin8bytes)
1146    mov       8(%rsi, %rdx), %rcx
1147    mov       8(%rdi, %rdx), %rax
1148L(diffin8bytes):
1149    cmp       %eax, %ecx
1150    jne       L(diffin4bytes)
1151    shr       $32, %rcx
1152    shr       $32, %rax
1153L(diffin4bytes):
1154    cmp       %cx, %ax
1155    jne       L(end)
1156    shr       $16, %ecx
1157    shr       $16, %eax
1158    jmp       L(end)
1159
1160    ALIGN (4)
1161L(end):
1162    and       $0xffff, %eax
1163    and       $0xffff, %ecx
1164    sub       %ecx, %eax
1165    ret
1166
1167END_FUNCTION MEMCMP
1168
1169    ALIGN (3)
1170L(table_64bytes):
1171    .int    JMPTBL (L(0bytes), L(table_64bytes))
1172    .int    JMPTBL (L(2bytes), L(table_64bytes))
1173    .int    JMPTBL (L(4bytes), L(table_64bytes))
1174    .int    JMPTBL (L(6bytes), L(table_64bytes))
1175    .int    JMPTBL (L(8bytes), L(table_64bytes))
1176    .int    JMPTBL (L(10bytes), L(table_64bytes))
1177    .int    JMPTBL (L(12bytes), L(table_64bytes))
1178    .int    JMPTBL (L(14bytes), L(table_64bytes))
1179    .int    JMPTBL (L(16bytes), L(table_64bytes))
1180    .int    JMPTBL (L(18bytes), L(table_64bytes))
1181    .int    JMPTBL (L(20bytes), L(table_64bytes))
1182    .int    JMPTBL (L(22bytes), L(table_64bytes))
1183    .int    JMPTBL (L(24bytes), L(table_64bytes))
1184    .int    JMPTBL (L(26bytes), L(table_64bytes))
1185    .int    JMPTBL (L(28bytes), L(table_64bytes))
1186    .int    JMPTBL (L(30bytes), L(table_64bytes))
1187    .int    JMPTBL (L(32bytes), L(table_64bytes))
1188    .int    JMPTBL (L(34bytes), L(table_64bytes))
1189    .int    JMPTBL (L(36bytes), L(table_64bytes))
1190    .int    JMPTBL (L(38bytes), L(table_64bytes))
1191    .int    JMPTBL (L(40bytes), L(table_64bytes))
1192    .int    JMPTBL (L(42bytes), L(table_64bytes))
1193    .int    JMPTBL (L(44bytes), L(table_64bytes))
1194    .int    JMPTBL (L(46bytes), L(table_64bytes))
1195    .int    JMPTBL (L(48bytes), L(table_64bytes))
1196    .int    JMPTBL (L(50bytes), L(table_64bytes))
1197    .int    JMPTBL (L(52bytes), L(table_64bytes))
1198    .int    JMPTBL (L(54bytes), L(table_64bytes))
1199    .int    JMPTBL (L(56bytes), L(table_64bytes))
1200    .int    JMPTBL (L(58bytes), L(table_64bytes))
1201    .int    JMPTBL (L(60bytes), L(table_64bytes))
1202    .int    JMPTBL (L(62bytes), L(table_64bytes))
1203    .int    JMPTBL (L(64bytes), L(table_64bytes))
1204    .int    JMPTBL (L(66bytes), L(table_64bytes))
1205    .int    JMPTBL (L(68bytes), L(table_64bytes))
1206    .int    JMPTBL (L(70bytes), L(table_64bytes))
1207    .int    JMPTBL (L(72bytes), L(table_64bytes))
1208    .int    JMPTBL (L(74bytes), L(table_64bytes))
1209    .int    JMPTBL (L(76bytes), L(table_64bytes))
1210    .int    JMPTBL (L(78bytes), L(table_64bytes))
1211