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