1 /* memcmp with SSE4.2, wmemcmp with SSE4.2
2 Copyright (C) 2010-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
24 # define MEMCMP __memcmp_sse4_2
27 # define CFI_PUSH(REG) \
28 cfi_adjust_cfa_offset (4); \
29 cfi_rel_offset (REG, 0)
31 # define CFI_POP(REG) \
32 cfi_adjust_cfa_offset (-4); \
35 # define PUSH(REG) pushl REG; CFI_PUSH (REG)
36 # define POP(REG) popl REG; CFI_POP (REG)
40 # define BLK2 BLK1 + 4
42 # define RETURN POP (%ebx); ret; CFI_PUSH (%ebx)
46 # define JMPTBL(I, B) I - B
48 /* Load an entry in a jump table into EBX and branch to it. TABLE is a
49 jump table with relative offsets. INDEX is a register contains the
50 index into the jump table. SCALE is the scale of INDEX. */
52 # define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \
53 /* We first load PC into EBX. */ \
55 /* Get the address of the jump table. */ \
56 addl $(TABLE - .), %ebx; \
57 /* Get the entry and convert the relative offset to the \
58 absolute address. */ \
59 addl (%ebx,INDEX,SCALE), %ebx; \
60 /* We loaded the jump table and adjusted EDX/ESI. Go. */ \
63 # define JMPTBL(I, B) I
65 /* Load an entry in a jump table into EBX and branch to it. TABLE is a
66 jump table with relative offsets. INDEX is a register contains the
67 index into the jump table. SCALE is the scale of INDEX. */
68 # define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \
69 jmp *TABLE(,INDEX,SCALE)
74 wmemcmp has to use SIGNED comparison for elements.
75 memcmp has to use UNSIGNED comparison for elements.
78 .section .text.sse4.2,"ax",@progbits
84 # ifdef USE_AS_WMEMCMP
98 # ifndef USE_AS_WMEMCMP
108 BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %ecx, 4)
110 # ifndef USE_AS_WMEMCMP
172 # ifdef USE_AS_WMEMCMP
174 /* for wmemcmp, case N == 1 */
182 jg L(find_diff_bigger)
196 # ifndef USE_AS_WMEMCMP
216 L(64bytesormore_loop):
223 movdqu 16(%eax), %xmm1
224 movdqu 16(%edx), %xmm2
229 movdqu 32(%eax), %xmm1
230 movdqu 32(%edx), %xmm2
235 movdqu 48(%eax), %xmm1
236 movdqu 48(%edx), %xmm2
243 jae L(64bytesormore_loop)
247 BRANCH_TO_JMPTBL_ENTRY(L(table_64bytes), %ecx, 4)
249 # ifdef USE_AS_WMEMCMP
251 /* Label needs only for table_64bytes filling */
267 # ifndef USE_AS_WMEMCMP
313 # ifndef USE_AS_WMEMCMP
316 movdqu -49(%eax), %xmm1
317 movdqu -49(%edx), %xmm2
323 movdqu -33(%eax), %xmm1
324 movdqu -33(%edx), %xmm2
349 movzbl -1(%eax), %ecx
358 movdqu -50(%eax), %xmm1
359 movdqu -50(%edx), %xmm2
365 movdqu -34(%eax), %xmm1
366 movdqu -34(%edx), %xmm2
391 movzwl -2(%eax), %ecx
392 movzwl -2(%edx), %ebx
403 movdqu -51(%eax), %xmm1
404 movdqu -51(%edx), %xmm2
410 movdqu -35(%eax), %xmm1
411 movdqu -35(%edx), %xmm2
436 movzwl -3(%eax), %ecx
437 movzwl -3(%edx), %ebx
443 movzbl -1(%eax), %eax
451 movdqu -52(%eax), %xmm1
452 movdqu -52(%edx), %xmm2
458 movdqu -36(%eax), %xmm1
459 movdqu -36(%edx), %xmm2
465 movdqu -20(%eax), %xmm1
466 movdqu -20(%edx), %xmm2
472 # ifndef USE_AS_WMEMCMP
482 # ifndef USE_AS_WMEMCMP
485 movdqu -53(%eax), %xmm1
486 movdqu -53(%edx), %xmm2
493 movdqu -37(%eax), %xmm1
494 movdqu -37(%edx), %xmm2
500 movdqu -21(%eax), %xmm1
501 movdqu -21(%edx), %xmm2
509 movzbl -1(%eax), %ecx
517 movdqu -54(%eax), %xmm1
518 movdqu -54(%edx), %xmm2
525 movdqu -38(%eax), %xmm1
526 movdqu -38(%edx), %xmm2
532 movdqu -22(%eax), %xmm1
533 movdqu -22(%edx), %xmm2
542 movzwl -2(%eax), %ecx
543 movzwl -2(%edx), %ebx
553 movdqu -55(%eax), %xmm1
554 movdqu -55(%edx), %xmm2
561 movdqu -39(%eax), %xmm1
562 movdqu -39(%edx), %xmm2
568 movdqu -23(%eax), %xmm1
569 movdqu -23(%edx), %xmm2
577 movzwl -3(%eax), %ecx
578 movzwl -3(%edx), %ebx
583 movzbl -1(%eax), %eax
591 movdqu -56(%eax), %xmm1
592 movdqu -56(%edx), %xmm2
599 movdqu -40(%eax), %xmm1
600 movdqu -40(%edx), %xmm2
606 movdqu -24(%eax), %xmm1
607 movdqu -24(%edx), %xmm2
613 # ifndef USE_AS_WMEMCMP
622 # ifndef USE_AS_WMEMCMP
632 # ifndef USE_AS_WMEMCMP
635 movdqu -57(%eax), %xmm1
636 movdqu -57(%edx), %xmm2
643 movdqu -41(%eax), %xmm1
644 movdqu -41(%edx), %xmm2
650 movdqu -25(%eax), %xmm1
651 movdqu -25(%edx), %xmm2
663 movzbl -1(%eax), %ecx
671 movdqu -58(%eax), %xmm1
672 movdqu -58(%edx), %xmm2
679 movdqu -42(%eax), %xmm1
680 movdqu -42(%edx), %xmm2
686 movdqu -26(%eax), %xmm1
687 movdqu -26(%edx), %xmm2
702 movzwl -2(%eax), %ecx
703 movzwl -2(%edx), %ebx
713 movdqu -59(%eax), %xmm1
714 movdqu -59(%edx), %xmm2
721 movdqu -43(%eax), %xmm1
722 movdqu -43(%edx), %xmm2
728 movdqu -27(%eax), %xmm1
729 movdqu -27(%edx), %xmm2
741 movzwl -3(%eax), %ecx
742 movzwl -3(%edx), %ebx
747 movzbl -1(%eax), %eax
755 movdqu -60(%eax), %xmm1
756 movdqu -60(%edx), %xmm2
763 movdqu -44(%eax), %xmm1
764 movdqu -44(%edx), %xmm2
770 movdqu -28(%eax), %xmm1
771 movdqu -28(%edx), %xmm2
777 # ifndef USE_AS_WMEMCMP
786 # ifndef USE_AS_WMEMCMP
795 # ifndef USE_AS_WMEMCMP
805 # ifndef USE_AS_WMEMCMP
808 movdqu -61(%eax), %xmm1
809 movdqu -61(%edx), %xmm2
816 movdqu -45(%eax), %xmm1
817 movdqu -45(%edx), %xmm2
823 movdqu -29(%eax), %xmm1
824 movdqu -29(%edx), %xmm2
843 movzbl -1(%eax), %ecx
851 movdqu -62(%eax), %xmm1
852 movdqu -62(%edx), %xmm2
859 movdqu -46(%eax), %xmm1
860 movdqu -46(%edx), %xmm2
866 movdqu -30(%eax), %xmm1
867 movdqu -30(%edx), %xmm2
883 movzwl -2(%eax), %ecx
884 movzwl -2(%edx), %ebx
894 movdqu -63(%eax), %xmm1
895 movdqu -63(%edx), %xmm2
902 movdqu -47(%eax), %xmm1
903 movdqu -47(%edx), %xmm2
909 movdqu -31(%eax), %xmm1
910 movdqu -31(%edx), %xmm2
927 movzwl -3(%eax), %ecx
928 movzwl -3(%edx), %ebx
933 movzbl -1(%eax), %eax
942 movdqu -64(%eax), %xmm1
943 movdqu -64(%edx), %xmm2
949 movdqu -48(%eax), %xmm1
950 movdqu -48(%edx), %xmm2
956 movdqu -32(%eax), %xmm1
957 movdqu -32(%edx), %xmm2
964 # ifndef USE_AS_WMEMCMP
973 # ifndef USE_AS_WMEMCMP
982 # ifndef USE_AS_WMEMCMP
991 # ifndef USE_AS_WMEMCMP
1001 # ifndef USE_AS_WMEMCMP
1056 # ifndef USE_AS_WMEMCMP
1086 .section .rodata.sse4.2,"a",@progbits
1088 .type L(table_64bytes), @object
1089 # ifndef USE_AS_WMEMCMP
1091 .int JMPTBL (L(0bytes), L(table_64bytes))
1092 .int JMPTBL (L(1bytes), L(table_64bytes))
1093 .int JMPTBL (L(2bytes), L(table_64bytes))
1094 .int JMPTBL (L(3bytes), L(table_64bytes))
1095 .int JMPTBL (L(4bytes), L(table_64bytes))
1096 .int JMPTBL (L(5bytes), L(table_64bytes))
1097 .int JMPTBL (L(6bytes), L(table_64bytes))
1098 .int JMPTBL (L(7bytes), L(table_64bytes))
1099 .int JMPTBL (L(8bytes), L(table_64bytes))
1100 .int JMPTBL (L(9bytes), L(table_64bytes))
1101 .int JMPTBL (L(10bytes), L(table_64bytes))
1102 .int JMPTBL (L(11bytes), L(table_64bytes))
1103 .int JMPTBL (L(12bytes), L(table_64bytes))
1104 .int JMPTBL (L(13bytes), L(table_64bytes))
1105 .int JMPTBL (L(14bytes), L(table_64bytes))
1106 .int JMPTBL (L(15bytes), L(table_64bytes))
1107 .int JMPTBL (L(16bytes), L(table_64bytes))
1108 .int JMPTBL (L(17bytes), L(table_64bytes))
1109 .int JMPTBL (L(18bytes), L(table_64bytes))
1110 .int JMPTBL (L(19bytes), L(table_64bytes))
1111 .int JMPTBL (L(20bytes), L(table_64bytes))
1112 .int JMPTBL (L(21bytes), L(table_64bytes))
1113 .int JMPTBL (L(22bytes), L(table_64bytes))
1114 .int JMPTBL (L(23bytes), L(table_64bytes))
1115 .int JMPTBL (L(24bytes), L(table_64bytes))
1116 .int JMPTBL (L(25bytes), L(table_64bytes))
1117 .int JMPTBL (L(26bytes), L(table_64bytes))
1118 .int JMPTBL (L(27bytes), L(table_64bytes))
1119 .int JMPTBL (L(28bytes), L(table_64bytes))
1120 .int JMPTBL (L(29bytes), L(table_64bytes))
1121 .int JMPTBL (L(30bytes), L(table_64bytes))
1122 .int JMPTBL (L(31bytes), L(table_64bytes))
1123 .int JMPTBL (L(32bytes), L(table_64bytes))
1124 .int JMPTBL (L(33bytes), L(table_64bytes))
1125 .int JMPTBL (L(34bytes), L(table_64bytes))
1126 .int JMPTBL (L(35bytes), L(table_64bytes))
1127 .int JMPTBL (L(36bytes), L(table_64bytes))
1128 .int JMPTBL (L(37bytes), L(table_64bytes))
1129 .int JMPTBL (L(38bytes), L(table_64bytes))
1130 .int JMPTBL (L(39bytes), L(table_64bytes))
1131 .int JMPTBL (L(40bytes), L(table_64bytes))
1132 .int JMPTBL (L(41bytes), L(table_64bytes))
1133 .int JMPTBL (L(42bytes), L(table_64bytes))
1134 .int JMPTBL (L(43bytes), L(table_64bytes))
1135 .int JMPTBL (L(44bytes), L(table_64bytes))
1136 .int JMPTBL (L(45bytes), L(table_64bytes))
1137 .int JMPTBL (L(46bytes), L(table_64bytes))
1138 .int JMPTBL (L(47bytes), L(table_64bytes))
1139 .int JMPTBL (L(48bytes), L(table_64bytes))
1140 .int JMPTBL (L(49bytes), L(table_64bytes))
1141 .int JMPTBL (L(50bytes), L(table_64bytes))
1142 .int JMPTBL (L(51bytes), L(table_64bytes))
1143 .int JMPTBL (L(52bytes), L(table_64bytes))
1144 .int JMPTBL (L(53bytes), L(table_64bytes))
1145 .int JMPTBL (L(54bytes), L(table_64bytes))
1146 .int JMPTBL (L(55bytes), L(table_64bytes))
1147 .int JMPTBL (L(56bytes), L(table_64bytes))
1148 .int JMPTBL (L(57bytes), L(table_64bytes))
1149 .int JMPTBL (L(58bytes), L(table_64bytes))
1150 .int JMPTBL (L(59bytes), L(table_64bytes))
1151 .int JMPTBL (L(60bytes), L(table_64bytes))
1152 .int JMPTBL (L(61bytes), L(table_64bytes))
1153 .int JMPTBL (L(62bytes), L(table_64bytes))
1154 .int JMPTBL (L(63bytes), L(table_64bytes))
1155 .int JMPTBL (L(64bytes), L(table_64bytes))
1158 .int JMPTBL (L(0bytes), L(table_64bytes))
1159 .int JMPTBL (L(unreal_case), L(table_64bytes))
1160 .int JMPTBL (L(unreal_case), L(table_64bytes))
1161 .int JMPTBL (L(unreal_case), L(table_64bytes))
1162 .int JMPTBL (L(4bytes), L(table_64bytes))
1163 .int JMPTBL (L(unreal_case), L(table_64bytes))
1164 .int JMPTBL (L(unreal_case), L(table_64bytes))
1165 .int JMPTBL (L(unreal_case), L(table_64bytes))
1166 .int JMPTBL (L(8bytes), L(table_64bytes))
1167 .int JMPTBL (L(unreal_case), L(table_64bytes))
1168 .int JMPTBL (L(unreal_case), L(table_64bytes))
1169 .int JMPTBL (L(unreal_case), L(table_64bytes))
1170 .int JMPTBL (L(12bytes), L(table_64bytes))
1171 .int JMPTBL (L(unreal_case), L(table_64bytes))
1172 .int JMPTBL (L(unreal_case), L(table_64bytes))
1173 .int JMPTBL (L(unreal_case), L(table_64bytes))
1174 .int JMPTBL (L(16bytes), L(table_64bytes))
1175 .int JMPTBL (L(unreal_case), L(table_64bytes))
1176 .int JMPTBL (L(unreal_case), L(table_64bytes))
1177 .int JMPTBL (L(unreal_case), L(table_64bytes))
1178 .int JMPTBL (L(20bytes), L(table_64bytes))
1179 .int JMPTBL (L(unreal_case), L(table_64bytes))
1180 .int JMPTBL (L(unreal_case), L(table_64bytes))
1181 .int JMPTBL (L(unreal_case), L(table_64bytes))
1182 .int JMPTBL (L(24bytes), L(table_64bytes))
1183 .int JMPTBL (L(unreal_case), L(table_64bytes))
1184 .int JMPTBL (L(unreal_case), L(table_64bytes))
1185 .int JMPTBL (L(unreal_case), L(table_64bytes))
1186 .int JMPTBL (L(28bytes), L(table_64bytes))
1187 .int JMPTBL (L(unreal_case), L(table_64bytes))
1188 .int JMPTBL (L(unreal_case), L(table_64bytes))
1189 .int JMPTBL (L(unreal_case), L(table_64bytes))
1190 .int JMPTBL (L(32bytes), L(table_64bytes))
1191 .int JMPTBL (L(unreal_case), L(table_64bytes))
1192 .int JMPTBL (L(unreal_case), L(table_64bytes))
1193 .int JMPTBL (L(unreal_case), L(table_64bytes))
1194 .int JMPTBL (L(36bytes), L(table_64bytes))
1195 .int JMPTBL (L(unreal_case), L(table_64bytes))
1196 .int JMPTBL (L(unreal_case), L(table_64bytes))
1197 .int JMPTBL (L(unreal_case), L(table_64bytes))
1198 .int JMPTBL (L(40bytes), L(table_64bytes))
1199 .int JMPTBL (L(unreal_case), L(table_64bytes))
1200 .int JMPTBL (L(unreal_case), L(table_64bytes))
1201 .int JMPTBL (L(unreal_case), L(table_64bytes))
1202 .int JMPTBL (L(44bytes), L(table_64bytes))
1203 .int JMPTBL (L(unreal_case), L(table_64bytes))
1204 .int JMPTBL (L(unreal_case), L(table_64bytes))
1205 .int JMPTBL (L(unreal_case), L(table_64bytes))
1206 .int JMPTBL (L(48bytes), L(table_64bytes))
1207 .int JMPTBL (L(unreal_case), L(table_64bytes))
1208 .int JMPTBL (L(unreal_case), L(table_64bytes))
1209 .int JMPTBL (L(unreal_case), L(table_64bytes))
1210 .int JMPTBL (L(52bytes), L(table_64bytes))
1211 .int JMPTBL (L(unreal_case), L(table_64bytes))
1212 .int JMPTBL (L(unreal_case), L(table_64bytes))
1213 .int JMPTBL (L(unreal_case), L(table_64bytes))
1214 .int JMPTBL (L(56bytes), L(table_64bytes))
1215 .int JMPTBL (L(unreal_case), L(table_64bytes))
1216 .int JMPTBL (L(unreal_case), L(table_64bytes))
1217 .int JMPTBL (L(unreal_case), L(table_64bytes))
1218 .int JMPTBL (L(60bytes), L(table_64bytes))
1219 .int JMPTBL (L(unreal_case), L(table_64bytes))
1220 .int JMPTBL (L(unreal_case), L(table_64bytes))
1221 .int JMPTBL (L(unreal_case), L(table_64bytes))
1222 .int JMPTBL (L(64bytes), L(table_64bytes))