master: arm64 utf8-strlen: test for null and non-ascii at the same time
stassats via Sbcl-commits <[email protected]>
| Newsgroups | gmane.lisp.steel-bank.cvs |
|---|---|
| Message-ID | <[email protected]> |
The branch "master" has been updated in SBCL:
via b561a0680fb5988b86ca18a54a943c0247682f81 (commit)
from c68fdd2af1a169f4fb02e0e9fa45862a4c08851f (commit)
- Log -----------------------------------------------------------------
commit b561a0680fb5988b86ca18a54a943c0247682f81
Author: Stas Boukarev <[email protected]>
Date: Mon Aug 10 07:06:34 2026 +0300
arm64 utf8-strlen: test for null and non-ascii at the same time
---
src/code/arm64-simd.lisp | 8 ++++----
src/code/x86-64-simd.lisp | 23 +++++++++--------------
2 files changed, 13 insertions(+), 18 deletions(-)
diff --git a/src/code/arm64-simd.lisp b/src/code/arm64-simd.lisp
index 489bdc747..54fb947b8 100644
--- a/src/code/arm64-simd.lisp
+++ b/src/code/arm64-simd.lisp
@@ -2050,10 +2050,10 @@
(inst sub current current tmp1 :16b)
ASCII
- (inst uminv tmp1 current :16b)
- (inst fmov tmp (reg-in-sc tmp1 'single-reg))
- (inst cbz tmp ASCII-TAIL)
- (check-ascii current tmp1 NON-ASCII :16b)
+ (inst sminv tmp1 current :16b)
+ (inst smov tmp tmp1 0 :b)
+ (inst cmp tmp 0) ;; either a null or a non-ascii character
+ (inst b :le ASCII-TAIL)
(inst ldr current (@ ptr 16 :pre-index))
(inst b ASCII)
diff --git a/src/code/x86-64-simd.lisp b/src/code/x86-64-simd.lisp
index 0421f684c..432c6fea4 100644
--- a/src/code/x86-64-simd.lisp
+++ b/src/code/x86-64-simd.lisp
@@ -2081,31 +2081,26 @@
(inst vpxor zeros zeros zeros)
ASCII
- (inst vpcmpeqb tmp1 current zeros)
+ ;; If everything is greater than zero then it's ascii without a null
+ (inst vpcmpgtb tmp1 current zeros)
(inst vpmovmskb tmp tmp1)
- (inst test :dword tmp tmp)
+ (inst xor :dword tmp -1) ;; affects flags, unlike NOT
(inst jmp :nz ASCII-TAIL)
- (inst vpmovmskb tmp current)
- (inst test :dword tmp tmp)
- (inst jmp :nz NON-ASCII)
-
(inst add ptr 32)
(inst vmovdqa current (ea ptr))
(inst jmp ASCII)
ASCII-TAIL
- (inst bsf :dword tmp tmp)
+ (inst vpmovmskb byte-length current) ;; non-ascii mask
- (inst vpmovmskb byte-length current)
- (inst test :dword byte-length byte-length)
- (inst jmp :z ALL-ASCII-DONE)
+ (inst bsf :dword tmp tmp) ;; the first 0 or non-ascii bit
- (inst bsf :dword byte-length byte-length)
- (inst cmp :dword byte-length tmp)
- (inst jmp :b NON-ASCII)
+ ;; If the first set bit is present in the non-ascii mask then
+ ;; the null-terminator is after it (or absent)
+ (inst bt :dword byte-length tmp)
+ (inst jmp :c NON-ASCII)
- ALL-ASCII-DONE
(inst add ptr tmp)
(inst sub ptr bytes)
(inst mov byte-length ptr)
-----------------------------------------------------------------------
hooks/post-receive
--
SBCL