master: avx2 simd-character-string-utf8-length

stassats via Sbcl-commits <[email protected]> Sun, 28 Jun 2026 16:49:48 +0000
Newsgroups gmane.lisp.steel-bank.cvs
Message-ID <[email protected]>
The branch "master" has been updated in SBCL:
       via  2206fab7cce2575ff687038378b8cf9df627cee2 (commit)
      from  e2165ebf7679b09d75b515cd7f2568388db0b921 (commit)

- Log -----------------------------------------------------------------
commit 2206fab7cce2575ff687038378b8cf9df627cee2
Author: Stas Boukarev <[email protected]>
Date:   Sun Jun 28 19:34:57 2026 +0300

    avx2 simd-character-string-utf8-length
---
 src/code/x86-64-simd.lisp | 111 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 111 insertions(+)

diff --git a/src/code/x86-64-simd.lisp b/src/code/x86-64-simd.lisp
index b42b6a151..09ac9b6d6 100644
--- a/src/code/x86-64-simd.lisp
+++ b/src/code/x86-64-simd.lisp
@@ -2024,3 +2024,114 @@
         (inst mov res total-bytes)
         DONE
         (inst vzeroupper)))))
+
+(def-variant sb-impl::simd-character-string-utf8-length :avx2 (string)
+  (with-pinned-objects (string)
+    (inline-vop
+        (((ptr sap-reg t) (vector-sap string))
+         ((length any-reg t) (length string))
+
+         ((chars-left   unsigned-reg))
+         ((tmp          unsigned-reg))
+
+         ;; 128-bit registers because strings are double-word aligned
+         ((c-7f         int-sse-reg))
+         ((c-7ff        int-sse-reg))
+         ((c-ffff       int-sse-reg))
+         ((c-1b         int-sse-reg))
+
+         ((extra-len    int-sse-reg))
+         ((errors       int-sse-reg))
+
+         ((current      int-sse-reg))
+         ((tmp1         int-sse-reg))
+         ((mask         int-sse-reg)))
+
+        ((res descriptor-reg t :from :load)
+         (all-ascii descriptor-reg t :from :load))
+
+      (inst mov res length)
+      (load-symbol all-ascii t)
+
+      (inst test length length)
+      (inst jmp :z DONE)
+
+      (inst mov chars-left length)
+      (inst shr chars-left n-fixnum-tag-bits)
+
+      (inst vmovdqa c-7f (register-inline-constant
+                          :sse (concat-ub 32 (loop repeat 4 collect #x7F))))
+
+      ASCII-LOOP
+      (inst vmovdqa current (ea ptr))
+      (inst add ptr 16)
+
+      (inst vpcmpgtd tmp1 current c-7f)
+      (inst vptest tmp1 tmp1)
+      (inst jmp :nz NON-ASCII)
+
+      (inst sub chars-left 4)
+      (inst jmp :g ASCII-LOOP)
+      (inst jmp DONE)
+
+      NON-ASCII
+      (inst mov res null-tn)
+      (inst mov all-ascii null-tn)
+
+      (inst vpxor extra-len extra-len extra-len)
+      (inst vpxor errors errors errors)
+
+      (inst vmovdqa c-7ff (register-inline-constant
+                           :sse (concat-ub 32 (loop repeat 4 collect #x7FF))))
+      (inst vmovdqa c-ffff (register-inline-constant
+                            :sse (concat-ub 32 (loop repeat 4 collect #xFFFF))))
+      (inst vmovdqa c-1b (register-inline-constant
+                          :sse (concat-ub 32 (loop repeat 4 collect #x1B))))
+
+      (inst jmp START)
+
+      LOOP
+      (inst sub chars-left 4)
+      (inst jmp :le EXIT)
+      (inst vmovdqa current (ea ptr))
+      (inst add ptr 16)
+
+      ;; ASCII fast path
+      (inst vpcmpgtd tmp1 current c-7f)
+      (inst vptest tmp1 tmp1)
+      (inst jmp :z LOOP)
+
+      START
+      ;; Check for surrogates #xD800-#xDFFF
+      (inst vpsrld tmp1 current 11)
+      (inst vpcmpeqd tmp1 tmp1 c-1b)
+      (inst vpor errors errors tmp1)
+
+      (inst vpcmpgtd tmp1 current c-7f)
+
+      (inst vpcmpgtd mask current c-7ff)
+      (inst vpaddd tmp1 tmp1 mask)
+
+      (inst vpcmpgtd mask current c-ffff)
+      (inst vpaddd tmp1 tmp1 mask)
+
+      (inst vpsubd extra-len extra-len tmp1)
+
+      (inst jmp LOOP)
+
+      EXIT
+      (inst vptest errors errors)
+      (inst jmp :nz DONE)
+
+      (inst vpshufd tmp1 extra-len #b01001110)
+      (inst vpaddd tmp1 tmp1 extra-len)
+      (inst vpshufd mask tmp1 #b10110001)
+      (inst vpaddd tmp1 tmp1 mask)
+
+      (inst vmovd tmp tmp1)
+
+      (inst shl tmp n-fixnum-tag-bits)
+      (inst add tmp length)
+      (inst mov res tmp)
+
+      DONE)))

-----------------------------------------------------------------------


hooks/post-receive
-- 
SBCL