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