ENTRY(strchrnul)
mov %edi, %ecx
and $~0xf, %rdi # align to 16 byte
movdqa (%rdi), %xmm1
movd %esi, %xmm0
and $0xf, %ecx # distance from (%rdi) to start of string
pxor %xmm2, %xmm2
mov $-1, %edx
punpcklbw %xmm0, %xmm0 # c -> cc
shl %cl, %edx # bits corresponding to bytes in the string
punpcklwd %xmm0, %xmm0 # cc -> cccc
add $16, %rdi
/* check for match in head */
pcmpeqb %xmm1, %xmm2 # NUL bytes present?
pshufd $0, %xmm0, %xmm0 # cccc -> cccccccccccccccc
pcmpeqb %xmm0, %xmm1 # c present?
por %xmm2, %xmm1 # either present?
pmovmskb %xmm1, %eax
and %edx, %eax # match in the string?
jnz 1f
/* main loop unrolled twice */
ALIGN_TEXT 0: movdqa (%rdi), %xmm1
pxor %xmm2, %xmm2
pcmpeqb %xmm1, %xmm2 # NUL bytes present?
pcmpeqb %xmm0, %xmm1 # c present?
por %xmm2, %xmm1 # either present?
pmovmskb %xmm1, %eax
test %eax, %eax # match in the string?
jnz 2f
movdqa 16(%rdi), %xmm1
add $32, %rdi
pxor %xmm2, %xmm2
pcmpeqb %xmm1, %xmm2 # NUL bytes present?
pcmpeqb %xmm0, %xmm1 # c present?
por %xmm2, %xmm1 # either present?
pmovmskb %xmm1, %eax
test %eax, %eax # match in the string?
jz 0b
1: sub $16, %rdi # undo advance past buffer 2: tzcnt %eax, %eax # where is the match?
add %rdi, %rax # pointer to found c or NUL
ret
END(strchrnul)
ENTRY(strchr)
// if (*strchrnul(s, c) != c) return nullptr;
// We have to compare against c rather than '\0' to
// correctly handle strchr(s, '\0'), so we need the push/pop
// to get c into a suitable register for an x86-64 byte compare.
push %rbx
mov %esi, %ebx
call strchrnul
xor %ecx, %ecx
cmp %bl, (%rax)
cmovne %rcx, %rax
pop %rbx
ret
END(strchr)
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.