diff options
| author | Robert Clausecker <fuz@FreeBSD.org> | 2023-08-25 16:22:22 +0000 |
|---|---|---|
| committer | Robert Clausecker <fuz@FreeBSD.org> | 2023-08-25 19:21:54 +0000 |
| commit | 3d8ef251aa9dceabd57f7821a0e6749d35317db3 (patch) | |
| tree | d669fa04db73715db528a1ec843aee1dddca1ab6 /lib/libc/amd64/string | |
| parent | 247e8662d2c080c27937ec4d62e80b2358e8c74f (diff) | |
Diffstat (limited to 'lib/libc/amd64/string')
| -rw-r--r-- | lib/libc/amd64/string/strchrnul.S | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/lib/libc/amd64/string/strchrnul.S b/lib/libc/amd64/string/strchrnul.S index 9aa9591b07ca..0e70b02311d7 100644 --- a/lib/libc/amd64/string/strchrnul.S +++ b/lib/libc/amd64/string/strchrnul.S @@ -52,22 +52,25 @@ ARCHENTRY(__strchrnul, scalar) movabs $0x0101010101010101, %r8 mov (%rdi), %rax # load first word imul %r8, %rsi # replicate char 8 times - movabs $0x8080808080808080, %r9 /* * Unaligned input: align to 8 bytes. Then proceed the same - * way as with aligned input, but ignore matches before the - * beginning of the string. This is achieved by shifting r9 - * into r10 to have 0x00 bytes before the string begins. + * way as with aligned input, but prevent matches before the + * beginning of the string. This is achieved by oring 0x01 + * into each byte of the buffer before the string */ shl $3, %ecx - mov %r9, %r10 + mov %r8, %r10 add $8, %rdi - shl %cl, %r10 # 0x80 where the string is + shl %cl, %r10 # 0x01 where the string is + xor %r8, %r10 # 0x01 where it is not neg %r8 # negate 01..01 so we can use lea + movabs $0x8080808080808080, %r9 mov %rsi, %rcx xor %rax, %rcx # str ^ c + or %r10, %rax # str without NUL bytes before it + or %r10, %rcx # (str ^ c) without matches before it lea (%rax, %r8, 1), %rdx # str - 0x01..01 lea (%rcx, %r8, 1), %r11 # (str ^ c) - 0x01..01 not %rax # ~str @@ -75,7 +78,7 @@ ARCHENTRY(__strchrnul, scalar) and %rdx, %rax # (str - 0x01..01) & ~str and %r11, %rcx # ((str ^ c - 0x01..01) & ~(str ^ c) or %rcx, %rax # matches for both - and %r10, %rax # not including junk bytes or bytes before the string + and %r9, %rax # not including junk bytes jnz 1f /* main loop unrolled twice */ |
