X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fx86-64%2Farith.lisp;h=922962632595cac1b7a0356b6575adcab7a2f7c8;hb=91a5cbf7375439309fede4776d8debc7a132dc20;hp=311eb7840dc9618841d2c454f285957f64d9a4a8;hpb=60deeb7616b22ae52cf1dd8bbc2904a1a0d80ffd;p=sbcl.git diff --git a/src/compiler/x86-64/arith.lisp b/src/compiler/x86-64/arith.lisp index 311eb78..9229626 100644 --- a/src/compiler/x86-64/arith.lisp +++ b/src/compiler/x86-64/arith.lisp @@ -1890,6 +1890,77 @@ constant shift greater than word length"))) (move result digit) (move ecx count) (inst shl result :cl))) + +(define-vop (logand-bignum/c) + (:translate logand) + (:policy :fast-safe) + (:args (x :scs (descriptor-reg))) + (:arg-types bignum (:constant word)) + (:results (r :scs (unsigned-reg))) + (:info mask) + (:result-types unsigned-num) + (:generator 4 + (let ((mask (constantize mask))) + (cond ((or (integerp mask) + (location= x r)) + (loadw r x bignum-digits-offset other-pointer-lowtag) + (unless (eql mask -1) + (inst and r mask))) + (t + (inst mov r mask) + (inst and r (make-ea-for-object-slot x + bignum-digits-offset + other-pointer-lowtag))))))) + +;; Specialised mask-signed-field VOPs. +(define-vop (mask-signed-field-word/c) + (:translate sb!c::mask-signed-field) + (:policy :fast-safe) + (:args (x :scs (signed-reg unsigned-reg) :target r)) + (:arg-types (:constant (integer 0 64)) untagged-num) + (:results (r :scs (signed-reg))) + (:result-types signed-num) + (:info width) + (:generator 3 + (cond ((zerop width) + (zeroize r)) + ((= width 64) + (move r x)) + ((member width '(32 16 8)) + (inst movsx r (reg-in-size x (ecase width + (32 :dword) + (16 :word) + (8 :byte))))) + (t + (move r x) + (let ((delta (- n-word-bits width))) + (inst shl r delta) + (inst sar r delta)))))) + +(define-vop (mask-signed-field-bignum/c) + (:translate sb!c::mask-signed-field) + (:policy :fast-safe) + (:args (x :scs (descriptor-reg) :target r)) + (:arg-types (:constant (integer 0 64)) bignum) + (:results (r :scs (signed-reg))) + (:result-types signed-num) + (:info width) + (:generator 4 + (cond ((zerop width) + (zeroize r)) + ((member width '(8 16 32 64)) + (ecase width + (64 (loadw r x bignum-digits-offset other-pointer-lowtag)) + ((32 16 8) + (inst movsx r (make-ea (ecase width (32 :dword) (16 :word) (8 :byte)) + :base x + :disp (- (* bignum-digits-offset n-word-bytes) + other-pointer-lowtag)))))) + (t + (loadw r x bignum-digits-offset other-pointer-lowtag) + (let ((delta (- n-word-bits width))) + (inst shl r delta) + (inst sar r delta)))))) ;;;; static functions