master: mips: Implement integer-length vop without looping

snuglas via Sbcl-commits <[email protected]> Fri, 17 Jul 2026 19:51:30 +0000
Newsgroups gmane.lisp.steel-bank.cvs
Message-ID <[email protected]>
The branch "master" has been updated in SBCL:
       via  0aeedbcaf61cf8944848ad57c431caa529b9e5b7 (commit)
      from  e4cd2e2548718c3e4598769b2945f1b2c89bc6d8 (commit)

- Log -----------------------------------------------------------------
commit 0aeedbcaf61cf8944848ad57c431caa529b9e5b7
Author: Douglas Katzman <[email protected]>
Date:   Fri Jul 17 19:50:06 2026 +0000

    mips: Implement integer-length vop without looping
---
 src/compiler/mips/arith.lisp | 28 +++++++++++-----------------
 src/compiler/mips/insts.lisp | 12 ++++++++++++
 2 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/src/compiler/mips/arith.lisp b/src/compiler/mips/arith.lisp
index 9cb42b47d..b5d29d3cf 100644
--- a/src/compiler/mips/arith.lisp
+++ b/src/compiler/mips/arith.lisp
@@ -299,24 +299,18 @@
   (:translate integer-length)
   (:note "inline (signed-byte 32) integer-length")
   (:policy :fast-safe)
-  (:args (arg :scs (signed-reg) :target shift))
+  (:args (arg :scs (signed-reg)))
   (:arg-types signed-num)
-  (:results (res :scs (any-reg)))
-  (:result-types positive-fixnum)
-  (:temporary (:scs (non-descriptor-reg) :from (:argument 0)) shift)
-  (:generator 30
-      (move shift arg)
-      (inst bgez shift test)
-      (zeroize res)
-      (inst b test)
-      (inst nor shift shift)
-
-      LOOP
-      (inst addu res (fixnumize 1))
-
-      TEST
-      (inst bne shift loop)
-      (inst srl shift 1)))
+  (:results (res :scs (unsigned-reg)))
+  (:result-types unsigned-num)
+  (:temporary (:sc unsigned-reg) temp)
+  (:generator 5
+    (move temp arg)
+    (inst sra temp 31)
+    (inst xor temp arg) ; invert if negative
+    (inst clz res temp)
+    (inst li temp 32)
+    (inst subu res temp res)))
 
 (define-vop (unsigned-byte-32-count)
   (:translate logcount)
diff --git a/src/compiler/mips/insts.lisp b/src/compiler/mips/insts.lisp
index ec70b8f0d..2417b256a 100644
--- a/src/compiler/mips/insts.lisp
+++ b/src/compiler/mips/insts.lisp
@@ -188,6 +188,7 @@
 (defconstant cop1-op #b010001)
 (defconstant cop2-op #b010010)
 (defconstant cop3-op #b010011)
+(defconstant special2-op #b011100)
 
 
 
@@ -568,6 +569,17 @@
   (:emitter
    (emit-shift-inst segment #b10 dst src1 src2)))
 
+(define-instruction clz (segment dst src)
+  (:declare (type tn dst src))
+  (:printer register ((op special2-op) (shamt nil) (funct #b100000)) '(:name :tab rd ", " rs))
+  (:dependencies (reads src) (writes dst))
+  (:delay 0)
+  (:emitter
+   ;; "To be compliant with the MIPS32 and MIPS64 Architecture, software must place the same GPR number
+   ;; in both the rt and rd fields of the instruction. The operation of the instruction is UNPREDICTABLE
+   ;; if the rt and rd fields of the instruction contain different values."
+   (let ((d (reg-tn-encoding dst)))
+     (emit-register-inst segment special2-op (reg-tn-encoding src) d d 0 #b100000))))
 
 ;;;; Floating point math.
 

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


hooks/post-receive
-- 
SBCL