master: Shrink the table in simd-copy-utf8-sap-to-character-string
stassats via Sbcl-commits <[email protected]> Sun, 05 Jul 2026 23:58:04 +0000
| Newsgroups | gmane.lisp.steel-bank.cvs |
|---|---|
| Message-ID | <[email protected]> |
The branch "master" has been updated in SBCL:
via e5edefadf3d33c883d4564c8e4d1ca141ba80ae0 (commit)
from 9104b7ce06b159064916c9c4bce7a30381099a3b (commit)
- Log -----------------------------------------------------------------
commit e5edefadf3d33c883d4564c8e4d1ca141ba80ae0
Author: Stas Boukarev <[email protected]>
Date: Mon Jul 6 02:48:46 2026 +0300
Shrink the table in simd-copy-utf8-sap-to-character-string
From 4KB to 2.6KB by using an inverted index.
---
src/code/arm64-simd.lisp | 10 +++++-----
src/code/x86-64-simd.lisp | 22 ++++++++++------------
2 files changed, 15 insertions(+), 17 deletions(-)
diff --git a/src/code/arm64-simd.lisp b/src/code/arm64-simd.lisp
index e6ad660d7..f9e863281 100644
--- a/src/code/arm64-simd.lisp
+++ b/src/code/arm64-simd.lisp
@@ -1653,11 +1653,11 @@
(type (simple-array character (*)) string))
(let ((byte-index 0)
(char-index 0)
- (table (load-time-value (let ((table (make-array (* 256 16) :element-type '(unsigned-byte 8)
- :initial-element #xFF)))
- (loop for row below 256
+ (table (load-time-value (let ((table (make-array (* #b10101011 16) :element-type '(unsigned-byte 8)
+ :initial-element #xFF)))
+ (loop for row to #b10101010 ;; highest possible inverted index for compressing 1/2 bytes
do (loop with indexes = (loop for i below 8
- when (logbitp i row)
+ unless (logbitp i row)
collect (* i 2)
and
collect (1+ (* i 2)))
@@ -1720,7 +1720,7 @@
;; suitable for the lookup table
(inst ushr sh current 6 :8b)
(inst cmeq continuations sh mask-2 :8b)
- (inst bic starts powers continuations :8b)
+ (inst and starts powers continuations :8b)
(inst addv starts starts :8b)
(inst addv count continuations :8b)
(inst umov tmp starts 0 :b)
diff --git a/src/code/x86-64-simd.lisp b/src/code/x86-64-simd.lisp
index ecb3fc578..d63a87588 100644
--- a/src/code/x86-64-simd.lisp
+++ b/src/code/x86-64-simd.lisp
@@ -2273,11 +2273,11 @@
(type (simple-array character (*)) string))
(let ((byte-index 0)
(char-index 0)
- (table (load-time-value (let ((table (make-array (* 256 16) :element-type '(unsigned-byte 8)
- :initial-element #xFF)))
- (loop for row below 256
+ (table (load-time-value (let ((table (make-array (* #b10101011 16) :element-type '(unsigned-byte 8)
+ :initial-element #xFF)))
+ (loop for row to #b10101010 ;; highest possible inverted index for compressing 1/2 bytes
do (loop with indexes = (loop for i below 8
- when (logbitp i row)
+ unless (logbitp i row)
collect (* i 2)
and
collect (1+ (* i 2)))
@@ -2340,7 +2340,7 @@
LOOP
(inst vmovq current (ea byte-array byte-index))
- (inst vmovq next (ea 1 byte-array byte-index))
+ (inst vpmovzxbw next (ea 1 byte-array byte-index))
;; Check for 3 or 4 bytes
(inst vpsubusb temp current mask-df)
@@ -2352,13 +2352,9 @@
(inst vpand temp current mask-c0)
(inst vpcmpeqb temp temp mask-80)
(inst vpmovmskb tmp temp)
- (inst xor :dword tmp #xFF)
(inst shl :dword tmp 4)
- (inst vmovdqu temp (ea table tmp))
-
(inst vpmovzxbw packed current)
- (inst vpmovzxbw next next)
;; next is shifted by one,
;; construct a codepoint from two overlapping bytes,
@@ -2372,9 +2368,11 @@
(inst vpcmpgtw next packed mask-bf)
(inst vpblendvb packed packed combined next)
+
;; Remove the gaps left over from using two bytes as one codepoint
- (inst vpshufb packed packed temp)
+ (inst vpshufb packed packed (ea table tmp))
+ (inst xor :dword tmp #xFF0) ;; Count non-continuation bytes
(inst popcnt :dword tmp tmp)
;; Widen
@@ -2397,8 +2395,8 @@
(inst jmp :l DONE)
(inst inc byte-index)
- DONE
- (inst vzeroupper)))))
+ (inst vzeroupper)
+ DONE))))
(loop while (< byte-index length) do
(let ((b0 (sap-ref-8 sap byte-index)))
(cond
-----------------------------------------------------------------------
hooks/post-receive
--
SBCL