X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcompiler%2Fx86%2Farith.lisp;h=f9c09e1d1c321d9a8d209fb1701a39c85eb8b2da;hb=37b1ed8e9b6faa84832b8251998b5d0eb1f6b307;hp=b451680681875a178aba64406025771983b0cad7;hpb=e9984509712529c60d1158d44207d6abf11dccce;p=sbcl.git diff --git a/src/compiler/x86/arith.lisp b/src/compiler/x86/arith.lisp index b451680..f9c09e1 100644 --- a/src/compiler/x86/arith.lisp +++ b/src/compiler/x86/arith.lisp @@ -764,7 +764,7 @@ constant shift greater than word length"))) (:generator 5 (move result number) (move ecx amount) - (inst or ecx ecx) + (inst test ecx ecx) (inst jmp :ns positive) (inst neg ecx) (inst cmp ecx 31) @@ -793,7 +793,7 @@ constant shift greater than word length"))) (:generator 5 (move result number) (move ecx amount) - (inst or ecx ecx) + (inst test ecx ecx) (inst jmp :ns positive) (inst neg ecx) (inst cmp ecx 31) @@ -810,6 +810,52 @@ constant shift greater than word length"))) DONE)) +#!+ash-right-vops +(define-vop (fast-%ash/right/unsigned) + (:translate %ash/right) + (:policy :fast-safe) + (:args (number :scs (unsigned-reg) :target result) + (amount :scs (unsigned-reg) :target ecx)) + (:arg-types unsigned-num unsigned-num) + (:results (result :scs (unsigned-reg) :from (:argument 0))) + (:result-types unsigned-num) + (:temporary (:sc signed-reg :offset ecx-offset :from (:argument 1)) ecx) + (:generator 4 + (move result number) + (move ecx amount) + (inst shr result :cl))) + +#!+ash-right-vops +(define-vop (fast-%ash/right/signed) + (:translate %ash/right) + (:policy :fast-safe) + (:args (number :scs (signed-reg) :target result) + (amount :scs (unsigned-reg) :target ecx)) + (:arg-types signed-num unsigned-num) + (:results (result :scs (signed-reg) :from (:argument 0))) + (:result-types signed-num) + (:temporary (:sc signed-reg :offset ecx-offset :from (:argument 1)) ecx) + (:generator 4 + (move result number) + (move ecx amount) + (inst sar result :cl))) + +#!+ash-right-vops +(define-vop (fast-%ash/right/fixnum) + (:translate %ash/right) + (:policy :fast-safe) + (:args (number :scs (any-reg) :target result) + (amount :scs (unsigned-reg) :target ecx)) + (:arg-types tagged-num unsigned-num) + (:results (result :scs (any-reg) :from (:argument 0))) + (:result-types tagged-num) + (:temporary (:sc signed-reg :offset ecx-offset :from (:argument 1)) ecx) + (:generator 3 + (move result number) + (move ecx amount) + (inst sar result :cl) + (inst and result (lognot fixnum-tag-mask)))) + (in-package "SB!C") (defknown %lea (integer integer (member 1 2 4 8) (signed-byte 32)) @@ -905,7 +951,7 @@ constant shift greater than word length"))) (:generator 4 (move result number) (move ecx amount) - (inst or ecx ecx) + (inst test ecx ecx) (inst jmp :ns positive) (inst neg ecx) (inst xor zero zero) @@ -1139,10 +1185,14 @@ constant shift greater than word length"))) cond unsigned)) (:generator ,cost - (inst cmp x - ,(if (eq suffix '-c/fixnum) - '(fixnumize y) - 'y))))) + (cond ((and (sc-is x any-reg signed-reg unsigned-reg) + (eql y 0)) + (inst test x x)) + (t + (inst cmp x + ,(if (eq suffix '-c/fixnum) + '(fixnumize y) + 'y))))))) '(/fixnum -c/fixnum /signed -c/signed /unsigned -c/unsigned) '(4 3 6 5 6 5) '(t t t t nil nil))))) @@ -1316,6 +1366,22 @@ constant shift greater than word length"))) ;; (no -C variant as x86 MUL instruction doesn't take an immediate) (def * nil)) +(define-modular-fun %negate-mod32 (x) %negate :untagged nil 32) +(define-vop (%negate-mod32) + (:translate %negate-mod32) + (:policy :fast-safe) + (:args (x :scs (unsigned-reg) :target r)) + (:arg-types unsigned-num) + (:results (r :scs (unsigned-reg))) + (:result-types unsigned-num) + (:generator 3 + (move r x) + (inst neg r))) + +(define-modular-fun %negate-modfx (x) %negate :tagged t #.(- n-word-bits + n-fixnum-tag-bits)) +(define-vop (%negate-modfx fast-negate/fixnum) + (:translate %negate-modfx)) (define-vop (fast-ash-left-mod32-c/unsigned=>unsigned fast-ash-c/unsigned=>unsigned) @@ -1464,7 +1530,7 @@ constant shift greater than word length"))) (:arg-types unsigned-num) (:conditional :ns) (:generator 3 - (inst or digit digit))) + (inst test digit digit))) ;;; For add and sub with carry the sc of carry argument is any-reg so