aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/amd64/string
diff options
context:
space:
mode:
authorRobert Clausecker <fuz@FreeBSD.org>2023-09-11 23:56:30 +0000
committerRobert Clausecker <fuz@FreeBSD.org>2023-09-12 02:58:43 +0000
commit52d4a4d4e0dedc72bc33082a3f84c2d0fd6f2cbb (patch)
treed8cc9182616c717fbd653257cbdd5d1d3a6f90d0 /lib/libc/amd64/string
parentfafb03ab4254ab0d3927bc8ec22e4ba432efdbeb (diff)
Diffstat (limited to 'lib/libc/amd64/string')
-rw-r--r--lib/libc/amd64/string/strcspn.S25
1 files changed, 15 insertions, 10 deletions
diff --git a/lib/libc/amd64/string/strcspn.S b/lib/libc/amd64/string/strcspn.S
index de409db6d472..53100eeea9a5 100644
--- a/lib/libc/amd64/string/strcspn.S
+++ b/lib/libc/amd64/string/strcspn.S
@@ -259,27 +259,32 @@ ARCHENTRY(strcspn, x86_64_v2)
movdqu 48(%rsp, %rcx, 1), %xmm3 # second part of set
/* set is 17--32 bytes in size */
- pcmpistri $0, %xmm0, %xmm2 # match in head?
- jbe .Lheadmatchv2
- pcmpistri $0, %xmm0, %xmm3 # ZF=1 not possible here
+ pcmpistri $0, %xmm0, %xmm2 # match in first set half?
jb .Lheadmatchv2
+ pcmpistri $0, %xmm0, %xmm3 # match in second set half or end of string?
+ jbe .Lheadmatchv2
ALIGN_TEXT
0: movdqa (%rax), %xmm0
pcmpistri $0, %xmm0, %xmm2
- jbe 1b
+ jb 2f # match in first set half?
pcmpistri $0, %xmm0, %xmm3
- jb 1f # ZF=1 not possible here
+ jbe 1f # match in second set half or end of string?
movdqa 16(%rax), %xmm0
add $32, %rax
pcmpistri $0, %xmm0, %xmm2
- jbe 3b
+ jb 3f # match in first set half?
pcmpistri $0, %xmm0, %xmm3
- jae 0b # ZF=1 not possible here
+ ja 0b # neither match in 2nd half nor string end?
- sub $16, %rax # go back to second half
-1: add %rcx, %rax
- sub %rdi, %rax
+3: lea -16(%rax), %rax # go back to second half
+1: jc 2f # jump if match found
+ pxor %xmm1, %xmm1
+ pcmpeqb %xmm1, %xmm0 # where is the NUL byte?
+ pmovmskb %xmm0, %ecx
+ tzcnt %ecx, %ecx # location of NUL byte in (%rax)
+2: sub %rdi, %rax # offset of %xmm0 from beginning of string
+ add %rcx, %rax # prefix length before match/NUL
leave
ret