master: Move instructions around in simd-copy-utf8-sap-to-character-string
stassats via Sbcl-commits <[email protected]> Mon, 20 Jul 2026 05:48:03 +0000
| Newsgroups | gmane.lisp.steel-bank.cvs |
|---|---|
| Message-ID | <[email protected]> |
The branch "master" has been updated in SBCL:
via f55213a95b1f5f36faba9ce4379823e331f0d84d (commit)
from da7d90ca9a80a8e73c79ddc39dc8fb9ae10e1b87 (commit)
- Log -----------------------------------------------------------------
commit f55213a95b1f5f36faba9ce4379823e331f0d84d
Author: Stas Boukarev <[email protected]>
Date: Mon Jul 20 08:46:22 2026 +0300
Move instructions around in simd-copy-utf8-sap-to-character-string
---
src/code/arm64-simd.lisp | 30 +++++++++++++++++-------------
src/code/x86-64-simd.lisp | 33 +++++++++++++++++----------------
tests/utf-8.impure.lisp | 24 +++++++++++++++---------
3 files changed, 49 insertions(+), 38 deletions(-)
diff --git a/src/code/arm64-simd.lisp b/src/code/arm64-simd.lisp
index f461b8d09..0e6395c27 100644
--- a/src/code/arm64-simd.lisp
+++ b/src/code/arm64-simd.lisp
@@ -1662,7 +1662,6 @@
((byte-array-length unsigned-reg) byte-array-length)
((index unsigned-reg))
((suffix unsigned-reg))
- ((produced unsigned-reg))
((ptr any-reg))
((bytes complex-double-reg t))
((bytes16 complex-double-reg t))
@@ -1694,6 +1693,7 @@
(assemble ()
(move byte-array byte-array*)
+ (inst movi c-c0 #xC0 :16b)
(inst mov byte-index 0)
(inst mov char-index 0)
(load-inline-constant powers :qword #x8040201008040201)
@@ -1721,14 +1721,16 @@
(inst b :lt DONE)
(inst add ptr byte-array byte-index)
- (inst ldr (reg-in-sc bytes 'double-reg) (@ ptr))
- (inst ldr (reg-in-sc next 'double-reg) (@ ptr 1))
+ (inst ldr bytes (@ ptr) :d)
+
(inst umaxv temp bytes :8b)
- (inst umov tmp-tn temp 0 :b)
- (inst cmp tmp-tn #xE0) ;; 3 or 4 bytes
+ (inst umov index temp 0 :b)
+ (inst cmp index #xE0) ;; 3 or 4 bytes
(inst b :ge full)
+ (inst ldr next (@ ptr 1) :d)
+
;; Build a bit pattern of non-continuation bytes
;; suitable for the lookup table
(inst cmge continuations c-c0 bytes :8b)
@@ -1775,7 +1777,6 @@
(convert-1-2 START-FULL)
START-FULL
- (inst movi c-c0 #xC0 :16b)
(inst movi c-ff #xFF :8h)
(inst movi c-4 4 :4s)
(load-inline-constant tag-clear :oword #x070F1F1F3F3F3F3F7F7F7F7F7F7F7F7F)
@@ -1798,14 +1799,17 @@
'(vector (unsigned-byte 8))))
FULL-LOOP
- (inst sub tmp-tn string-length char-index)
- (inst cmp tmp-tn 8)
- (inst b :lt DONE)
-
(inst sub tmp-tn byte-array-length byte-index)
+ FULL-LOOP-LENGTH-COMPUTED
(inst cmp tmp-tn 16)
(inst b :lt DONE)
+ (inst sub tmp-tn string-length char-index)
+ (inst cmp tmp-tn 8)
+ (inst b :lt DONE)
+
+
+
;; Process the leading bytes in the first 8 bytes, loading 16 bytes
;; so that the last leading byte might drag in 3 more bytes
(inst ldr bytes (@ byte-array byte-index))
@@ -1834,7 +1838,7 @@
(inst addv temp2 temp :8b)
;; A negated number of produced characters
- (inst smov produced temp2 0 :b)
+ (inst smov suffix temp2 0 :b)
;; Use the high 4 bits of each byte to get an and-mask that
;; will clear their tags
@@ -1870,13 +1874,13 @@
(inst add byte-index byte-index 8)
- (inst sub char-index char-index produced)
+ (inst sub char-index char-index suffix)
;; Can't re-enter the 1-2 loop if there were
;; continuation bytes into the next word, (and can't
;; add suffix to byte-index, as it will kill out of
;; order execution)
(inst cbnz suffix full-loop)
- (convert-1-2 FULL-LOOP)))
+ (convert-1-2 FULL-LOOP-LENGTH-COMPUTED)))
TAIL-16
(inst cmp tmp-tn 8)
(inst b :lt DONE)
diff --git a/src/code/x86-64-simd.lisp b/src/code/x86-64-simd.lisp
index f3eed8afe..b4bcbf111 100644
--- a/src/code/x86-64-simd.lisp
+++ b/src/code/x86-64-simd.lisp
@@ -2345,7 +2345,6 @@
(inst jmp :l DONE)
(inst vmovq current (ea byte-array byte-index))
- (inst vpmovzxbw next (ea 1 byte-array byte-index))
;; Check for 3 or 4 bytes
(inst vpsubusb x2 current c-df)
@@ -2356,9 +2355,11 @@
;; suitable for the lookup table
(inst vpcmpgtb x3 c-c0 current)
(inst vpmovmskb tmp2 x3)
-
(inst shl :dword tmp2 4)
+
+ ;; Widen to 16-bits
(inst vpmovzxbw x3 current)
+ (inst vpmovzxbw next (ea 1 byte-array byte-index))
;; next is shifted by one,
;; construct a codepoint from two overlapping bytes,
@@ -2371,7 +2372,6 @@
(inst vpcmpgtw next x3 c-bf)
(inst vpblendvb x3 x3 x4 next)
-
;; Remove the gaps left over from using two bytes as one codepoint
(inst vpshufb x3 x3 (ea table tmp2))
(inst xor :dword tmp2 #xFF0) ;; Count non-continuation bytes
@@ -2397,16 +2397,16 @@
START-FULL
- (inst mov tmp #xFF)
- (inst vmovd c-00ff tmp)
+ (inst mov tmp2 #xFF)
+ (inst vmovd c-00ff tmp2)
(inst vpbroadcastw c-00ff c-00ff)
- (inst mov tmp #x0F)
- (inst vmovd c-0f tmp)
+ (inst mov tmp2 #x0F)
+ (inst vmovd c-0f tmp2)
(inst vpbroadcastb c-0f c-0f)
- (inst mov tmp #x10000001)
- (inst vmovd c-shift tmp)
+ (inst mov tmp2 #x10000001)
+ (inst vmovd c-shift tmp2)
(inst vpbroadcastd c-shift c-shift)
(inst lea full-table
@@ -2429,18 +2429,19 @@
(inst vmovdqa tag-clear (register-inline-constant
:sse #x070F1F1F3F3F3F3F7F7F7F7F7F7F7F7F))
-
FULL-LOOP
- (move tmp string-length)
- (inst sub tmp char-index)
- (inst cmp tmp 8)
- (inst jmp :l DONE)
-
(move tmp byte-array-length)
(inst sub tmp byte-index)
+
+ FULL-LOOP-LENGTH-COMPUTED
(inst cmp tmp 16)
(inst jmp :l DONE)
+ (move tmp string-length)
+ (inst sub tmp char-index)
+ (inst cmp tmp 8)
+ (inst jmp :l DONE)
+
;; Process the leading bytes in the first 8 bytes, loading 16 bytes
;; so that the last leading byte might drag in 3 more bytes
(inst vmovdqu current (ea byte-array byte-index))
@@ -2496,7 +2497,7 @@
;; order execution)
(inst test :dword tmp tmp)
(inst jmp :nz FULL-LOOP)
- (convert-1-2 FULL-LOOP)))
+ (convert-1-2 FULL-LOOP-LENGTH-COMPUTED)))
TAIL-16
diff --git a/tests/utf-8.impure.lisp b/tests/utf-8.impure.lisp
index 711ccce40..15e9383ea 100644
--- a/tests/utf-8.impure.lisp
+++ b/tests/utf-8.impure.lisp
@@ -66,15 +66,21 @@
(compile 'decode-test)
(defun fill-random-string (string &optional ascii)
- (map-into string (if ascii
- (lambda ()
- (code-char (random 128)))
- (lambda ()
- (code-char (case (random 4)
- (0 (random 128))
- (1 (+ 128 (random (- 2048 128))))
- (2 (+ 2048 (random (- 50000 2048))))
- (3 (+ 65536 (random (- char-code-limit 65536))))))))))
+ (loop with i = 0
+ for width = (if ascii
+ 0
+ (random 4))
+ while (< i (length string))
+ do (loop repeat (1+ (random (- (length string) i)))
+ for char = (case width
+ (0 (random 128))
+ (1 (+ 128 (random (- 2048 128))))
+ (2 (+ 2048 (random (- 50000 2048))))
+ (3 (+ 65536 (random (- char-code-limit 65536)))))
+ do (setf (aref string i) (code-char char))
+ (incf i)))
+ string)
+
(defun strlen (bytes)
(sb-vm::simd-utf8-strlen (sb-sys:vector-sap bytes)))
(compile 'strlen)
-----------------------------------------------------------------------
hooks/post-receive
--
SBCL