Re: [Sbcl-commits] master: Recognize (integer-length (ldb (byte 64 0) (1- (logand n (- n))))) as ctz
Douglas Katzman via Sbcl-devel <[email protected]>
| Newsgroups | gmane.lisp.steel-bank.devel |
|---|---|
| Message-ID | <CAOrNasy4x0k3cjJH1d8p-AR+sD3ujGBOejcQO+VjoEm5gT9PUg@mail.gmail.com> |
I see what you're trying to do to support older CPUs that don't implement TZCNT, however this MOV is not technically correct. If the processor treats TZCNT just like BSF, then the destination register is *undefined (*https://www.felixcloutier.com/x86/bsf)*,* not *unaffected* when the input is 0. So the output could be zero or random bits. I realize that clang uses this technique, but my guess is they simply haven't gotten complaints. gcc takes the manufacturer's spec at face value, and uses a pedantically correct solution to fixup the result if the input was zero testq %rdi, %rdi movl $64, %eax cmovne %edx, %eax > > +(define-vop () > + (:translate count-trailing-zeros) > + (:policy :fast-safe) > + (:args (arg :scs (signed-reg unsigned-reg) :to :save)) > + (:arg-types (:or signed-num unsigned-num)) > + (:results (res :scs (unsigned-reg))) > + (:result-types unsigned-num) > + (:generator 5 > + (inst mov res 64) > + (inst tzcnt res arg))) > _______________________________________________ Sbcl-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/sbcl-devel