X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fx86-64%2Fmove.lisp;h=423a0b967c2413c21f11f1e8820a11f5ffc2e905;hb=6794373d588cef4333fbbb9d04b931ae0a414a7f;hp=cc0a777b938efd88032dd1c1accee69a61130767;hpb=39117fb4cade75e692196cfca1ae3c320546a254;p=sbcl.git diff --git a/src/compiler/x86-64/move.lisp b/src/compiler/x86-64/move.lisp index cc0a777..423a0b9 100644 --- a/src/compiler/x86-64/move.lisp +++ b/src/compiler/x86-64/move.lisp @@ -256,26 +256,50 @@ ;;; Arg is a fixnum or bignum, figure out which and load if necessary. +#-#.(cl:if (cl:= sb!vm:n-fixnum-tag-bits 1) '(:and) '(:or)) (define-vop (move-to-word/integer) - (:args (x :scs (descriptor-reg) :target eax)) + (:args (x :scs (descriptor-reg) :target rax)) (:results (y :scs (signed-reg unsigned-reg))) (:note "integer to untagged word coercion") - (:temporary (:sc unsigned-reg :offset eax-offset - :from (:argument 0) :to (:result 0) :target y) eax) + ;; I'm not convinced that increasing the demand for rAX is + ;; better than adding 1 byte to some instruction encodings. + ;; I'll leave it alone though. + (:temporary (:sc unsigned-reg :offset rax-offset + :from (:argument 0) :to (:result 0) :target y) rax) (:generator 4 - (move eax x) + (move rax x) (inst test al-tn fixnum-tag-mask) (inst jmp :z FIXNUM) - (loadw y eax bignum-digits-offset other-pointer-lowtag) + (loadw y rax bignum-digits-offset other-pointer-lowtag) (inst jmp DONE) FIXNUM - (inst sar eax n-fixnum-tag-bits) - (move y eax) + (inst sar rax n-fixnum-tag-bits) + (move y rax) DONE)) + +#+#.(cl:if (cl:= sb!vm:n-fixnum-tag-bits 1) '(:and) '(:or)) +(define-vop (move-to-word/integer) + (:args (x :scs (descriptor-reg) :target y)) + (:results (y :scs (signed-reg unsigned-reg))) + (:note "integer to untagged word coercion") + (:temporary (:sc unsigned-reg) backup) + (:generator 4 + (move y x) + (if (location= x y) + ;; It would be great if a principled way existed to advise GC of + ;; algebraic transforms such as 2*R being a conservative root. + ;; Until that is possible, emit straightforward code that uses + ;; a copy of the potential reference. + (move backup x) + (setf backup x)) + (inst sar y 1) ; optimistically assume it's a fixnum + (inst jmp :nc DONE) ; no carry implies tag was 0 + (loadw y backup bignum-digits-offset other-pointer-lowtag) + DONE)) + (define-move-vop move-to-word/integer :move (descriptor-reg) (signed-reg unsigned-reg)) - ;;; Result is a fixnum, so we can just shift. We need the result type ;;; restriction because of the control-stack ambiguity noted above. (define-vop (move-from-word/fixnum)