master: arm64: implement simd-copy-utf8-sap-to-character-string using NEON
stassats via Sbcl-commits <[email protected]> Sun, 28 Jun 2026 20:40:52 +0000
| Newsgroups | gmane.lisp.steel-bank.cvs |
|---|---|
| Message-ID | <[email protected]> |
The branch "master" has been updated in SBCL:
via db02ba3bce49baa7b7e414945d9b8be914b0b7f5 (commit)
from 7e81a161c78d6dc2200aab516d00917856da0f52 (commit)
- Log -----------------------------------------------------------------
commit db02ba3bce49baa7b7e414945d9b8be914b0b7f5
Author: Stas Boukarev <[email protected]>
Date: Sun Jun 28 23:39:48 2026 +0300
arm64: implement simd-copy-utf8-sap-to-character-string using NEON
---
src/code/arm64-simd.lisp | 46 ++++++++++++++++++++++++++++++++
src/code/external-formats/enc-basic.lisp | 13 +++++----
2 files changed, 52 insertions(+), 7 deletions(-)
diff --git a/src/code/arm64-simd.lisp b/src/code/arm64-simd.lisp
index 3df63084f..907bdf50d 100644
--- a/src/code/arm64-simd.lisp
+++ b/src/code/arm64-simd.lisp
@@ -584,6 +584,52 @@
(setf (sb-impl::buffer-head ibuf) (+ head copied))
(+ start copied))))
+#+sb-unicode
+(defun simd-copy-utf8-sap-to-character-string (sap string length)
+ (declare (optimize speed (safety 0))
+ (system-area-pointer sap)
+ (index length))
+ (let ((n (logand length -16)))
+ (with-pinned-objects-in-registers (string)
+ (inline-vop (((byte-array* sap-reg t) sap)
+ ((byte-array sap-reg t))
+ ((32-bit-array sap-reg t) (vector-sap string))
+ ((end unsigned-reg))
+ ((n any-reg) n)
+ ((bytes complex-double-reg))
+ ((16-bits complex-double-reg))
+ ((16-bits-2 complex-double-reg))
+ ((32-bits complex-double-reg t :offset 4))
+ ((32-bits-2 complex-double-reg t :offset 5))
+ ((32-bits-3 complex-double-reg t :offset 6))
+ ((32-bits-4 complex-double-reg t :offset 7)))
+ ()
+ (inst add end byte-array* (lsr n 1))
+ (inst mov byte-array byte-array*)
+ (inst b start)
+
+ LOOP
+ (inst ldr bytes (@ byte-array 16 :post-index))
+
+ (inst ushll 16-bits :8h bytes :8b)
+ (inst ushll 32-bits :4s 16-bits :4h)
+
+ (inst ushll2 16-bits-2 :8h bytes :16b)
+ (inst ushll2 32-bits-2 :4s 16-bits :8h)
+
+ (inst ushll 32-bits-3 :4s 16-bits-2 :4h)
+ (inst ushll2 32-bits-4 :4s 16-bits-2 :8h)
+ (inst st1 (list 32-bits 32-bits-2 32-bits-3 32-bits-4) (@ 32-bit-array 64 :post-index) :4s)
+
+ start
+ (inst cmp byte-array end)
+ (inst b :lt LOOP)
+
+ DONE))
+ (loop for i from n below length
+ do (setf (aref string i)
+ (code-char (sap-ref-8 sap i))))))
+
(defun simd-copy-utf8-to-base-string (start end string ibuf)
(declare (type index start end)
(optimize speed (safety 0)))
diff --git a/src/code/external-formats/enc-basic.lisp b/src/code/external-formats/enc-basic.lisp
index 929835f7c..221c4f922 100644
--- a/src/code/external-formats/enc-basic.lisp
+++ b/src/code/external-formats/enc-basic.lisp
@@ -664,7 +664,7 @@
(truly-the index (values (truncate string-offset 4))))))
;;; No validations
-#+(and sb-unicode 64-bit little-endian)
+#+(and sb-unicode 64-bit little-endian (not arm64))
(defun sb-vm::simd-copy-utf8-sap-to-character-string (sap string length)
(declare (index length)
(simple-character-string string)
@@ -673,6 +673,7 @@
(let* ((n (logand length (- sb-vm:n-word-bytes)))
(string-sap (vector-sap string))
(string-offset 0))
+ (declare (fixnum string-offset))
(loop for byte-offset below n by sb-vm:n-word-bytes
do
(let ((word (sap-ref-word sap byte-offset)))
@@ -692,12 +693,10 @@
(dpb (ldb (byte 8 56) word)
(byte 8 32)
(ldb (byte 8 48) word))))
- (incf string-offset (* 4 sb-vm:n-word-bytes))
- finally (let ((string-offset (truncate string-offset 4)))
- (loop for i from n below length
- do (setf (aref string string-offset)
- (code-char (sap-ref-8 sap i)))
- (incf string-offset)))))))
+ (incf string-offset (* 4 sb-vm:n-word-bytes)))
+ (loop for i from n below length
+ do (setf (aref string i)
+ (code-char (sap-ref-8 sap i)))))))
#+(and sb-unicode 64-bit little-endian)
(defun sb-vm::simd-copy-utf8-crlf-to-character-string-with-size (start end string ibuf size-buffer)
-----------------------------------------------------------------------
hooks/post-receive
--
SBCL