X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fx86%2Fmove.lisp;h=020f2182e8fec5765c1d369155f8f166a8356edc;hb=66cff1e1319861c080d563359afea284614b3a7f;hp=a8f47e121e76bab5a9a064a77e016cfdd453f49f;hpb=cea4896b2482b7b2b429c1631d774b4cfbc0efba;p=sbcl.git diff --git a/src/compiler/x86/move.lisp b/src/compiler/x86/move.lisp index a8f47e1..020f218 100644 --- a/src/compiler/x86/move.lisp +++ b/src/compiler/x86/move.lisp @@ -11,48 +11,44 @@ (in-package "SB!VM") -(define-move-function (load-immediate 1) (vop x y) +(define-move-fun (load-immediate 1) (vop x y) ((immediate) (any-reg descriptor-reg)) - (let ((val (tn-value x))) - (etypecase val - (integer - (if (zerop val) - (inst xor y y) - (inst mov y (fixnumize val)))) - (symbol - (load-symbol y val)) - (character - (inst mov y (logior (ash (char-code val) type-bits) - base-char-type)))))) + (let ((val (encode-value-if-immediate x))) + (if (zerop val) + (inst xor y y) + (inst mov y val)))) -(define-move-function (load-number 1) (vop x y) +(define-move-fun (load-number 1) (vop x y) ((immediate) (signed-reg unsigned-reg)) - (inst mov y (tn-value x))) + (let ((val (tn-value x))) + (if (zerop val) + (inst xor y y) + (inst mov y val)))) -(define-move-function (load-base-char 1) (vop x y) - ((immediate) (base-char-reg)) +(define-move-fun (load-character 1) (vop x y) + ((immediate) (character-reg)) (inst mov y (char-code (tn-value x)))) -(define-move-function (load-system-area-pointer 1) (vop x y) +(define-move-fun (load-system-area-pointer 1) (vop x y) ((immediate) (sap-reg)) (inst mov y (sap-int (tn-value x)))) -(define-move-function (load-constant 5) (vop x y) +(define-move-fun (load-constant 5) (vop x y) ((constant) (descriptor-reg any-reg)) (inst mov y x)) -(define-move-function (load-stack 5) (vop x y) +(define-move-fun (load-stack 5) (vop x y) ((control-stack) (any-reg descriptor-reg) - (base-char-stack) (base-char-reg) + (character-stack) (character-reg) (sap-stack) (sap-reg) (signed-stack) (signed-reg) (unsigned-stack) (unsigned-reg)) (inst mov y x)) -(define-move-function (store-stack 5) (vop x y) +(define-move-fun (store-stack 5) (vop x y) ((any-reg descriptor-reg) (control-stack) - (base-char-reg) (base-char-stack) + (character-reg) (character-stack) (sap-reg) (sap-stack) (signed-reg) (signed-stack) (unsigned-reg) (unsigned-stack)) @@ -61,101 +57,63 @@ ;;;; the MOVE VOP (define-vop (move) (:args (x :scs (any-reg descriptor-reg immediate) :target y - :load-if (not (location= x y)))) + :load-if (not (location= x y)))) (:results (y :scs (any-reg descriptor-reg) - :load-if - (not (or (location= x y) - (and (sc-is x any-reg descriptor-reg immediate) - (sc-is y control-stack)))))) + :load-if + (not (or (location= x y) + (and (sc-is x any-reg descriptor-reg immediate) + (sc-is y control-stack)))))) (:effects) (:affected) (:generator 0 (if (and (sc-is x immediate) - (sc-is y any-reg descriptor-reg control-stack)) - (let ((val (tn-value x))) - (etypecase val - (integer - (if (and (zerop val) (sc-is y any-reg descriptor-reg)) - (inst xor y y) - (inst mov y (fixnumize val)))) - (symbol - (inst mov y (+ nil-value (static-symbol-offset val)))) - (character - (inst mov y (logior (ash (char-code val) type-bits) - base-char-type))))) + (sc-is y any-reg descriptor-reg control-stack)) + (let ((val (encode-value-if-immediate x))) + (if (and (zerop val) (sc-is y any-reg descriptor-reg)) + (inst xor y y) + (inst mov y val))) (move y x)))) (define-move-vop move :move (any-reg descriptor-reg immediate) (any-reg descriptor-reg)) -;;; Make Move the check VOP for T so that type check generation +;;; Make MOVE the check VOP for T so that type check generation ;;; doesn't think it is a hairy type. This also allows checking of a ;;; few of the values in a continuation to fall out. (primitive-type-vop move (:check) t) -;;; The Move-Argument VOP is used for moving descriptor values into +;;; The MOVE-ARG VOP is used for moving descriptor values into ;;; another frame for argument or known value passing. ;;; ;;; Note: It is not going to be possible to move a constant directly ;;; to another frame, except if the destination is a register and in ;;; this case the loading works out. -(define-vop (move-argument) +(define-vop (move-arg) (:args (x :scs (any-reg descriptor-reg immediate) :target y - :load-if (not (and (sc-is y any-reg descriptor-reg) - (sc-is x control-stack)))) - (fp :scs (any-reg) - :load-if (not (sc-is y any-reg descriptor-reg)))) + :load-if (not (and (sc-is y any-reg descriptor-reg) + (sc-is x control-stack)))) + (fp :scs (any-reg) + :load-if (not (sc-is y any-reg descriptor-reg)))) (:results (y)) (:generator 0 (sc-case y ((any-reg descriptor-reg) (if (sc-is x immediate) - (let ((val (tn-value x))) - (etypecase val - (integer - (if (zerop val) - (inst xor y y) - (inst mov y (fixnumize val)))) - (symbol - (load-symbol y val)) - (character - (inst mov y (logior (ash (char-code val) type-bits) - base-char-type))))) - (move y x))) + (let ((val (encode-value-if-immediate x))) + (if (zerop val) + (inst xor y y) + (inst mov y val))) + (move y x))) ((control-stack) - (if (sc-is x immediate) - (let ((val (tn-value x))) - (if (= (tn-offset fp) esp-offset) - ;; C-call - (etypecase val - (integer - (storew (fixnumize val) fp (tn-offset y))) - (symbol - (storew (+ nil-value (static-symbol-offset val)) - fp (tn-offset y))) - (character - (storew (logior (ash (char-code val) type-bits) - base-char-type) - fp (tn-offset y)))) - ;; Lisp stack - (etypecase val - (integer - (storew (fixnumize val) fp (- (1+ (tn-offset y))))) - (symbol - (storew (+ nil-value (static-symbol-offset val)) - fp (- (1+ (tn-offset y))))) - (character - (storew (logior (ash (char-code val) type-bits) - base-char-type) - fp (- (1+ (tn-offset y)))))))) - (if (= (tn-offset fp) esp-offset) - ;; C-call - (storew x fp (tn-offset y)) - ;; Lisp stack - (storew x fp (- (1+ (tn-offset y)))))))))) + (let ((frame-offset (if (= (tn-offset fp) esp-offset) + ;; C-call + (tn-offset y) + ;; Lisp stack + (frame-word-offset (tn-offset y))))) + (storew (encode-value-if-immediate x) fp frame-offset)))))) -(define-move-vop move-argument :move-argument +(define-move-vop move-arg :move-arg (any-reg descriptor-reg) (any-reg descriptor-reg)) @@ -185,9 +143,9 @@ ;;; possible bignum arg SCs. (define-vop (move-to-word/fixnum) (:args (x :scs (any-reg descriptor-reg) :target y - :load-if (not (location= x y)))) + :load-if (not (location= x y)))) (:results (y :scs (signed-reg unsigned-reg) - :load-if (not (location= x y)))) + :load-if (not (location= x y)))) (:arg-types tagged-num) (:note "fixnum untagging") (:generator 1 @@ -213,12 +171,12 @@ (: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) + :from (:argument 0) :to (:result 0) :target y) eax) (:generator 4 (move eax x) (inst test al-tn 3) (inst jmp :z fixnum) - (loadw y eax bignum-digits-offset other-pointer-type) + (loadw y eax bignum-digits-offset other-pointer-lowtag) (inst jmp done) FIXNUM (inst sar eax 2) @@ -232,20 +190,20 @@ ;;; restriction because of the control-stack ambiguity noted above. (define-vop (move-from-word/fixnum) (:args (x :scs (signed-reg unsigned-reg) :target y - :load-if (not (location= x y)))) + :load-if (not (location= x y)))) (:results (y :scs (any-reg descriptor-reg) - :load-if (not (location= x y)))) + :load-if (not (location= x y)))) (:result-types tagged-num) (:note "fixnum tagging") (:generator 1 (cond ((and (sc-is x signed-reg unsigned-reg) - (not (location= x y))) - ;; Uses 7 bytes, but faster on the Pentium - (inst lea y (make-ea :dword :index x :scale 4))) - (t - ;; Uses: If x is a reg 2 + 3; if x = y uses only 3 bytes - (move y x) - (inst shl y 2))))) + (not (location= x y))) + ;; Uses 7 bytes, but faster on the Pentium + (inst lea y (make-ea :dword :index x :scale 4))) + (t + ;; Uses: If x is a reg 2 + 3; if x = y uses only 3 bytes + (move y x) + (inst shl y 2))))) (define-move-vop move-from-word/fixnum :move (signed-reg unsigned-reg) (any-reg descriptor-reg)) @@ -261,9 +219,9 @@ (:args (x :scs (signed-reg unsigned-reg) :target eax)) (:temporary (:sc unsigned-reg :offset eax-offset :from (:argument 0)) eax) (:temporary (:sc unsigned-reg :offset ebx-offset :to (:result 0) :target y) - ebx) + ebx) (:temporary (:sc unsigned-reg :offset ecx-offset - :from (:argument 0) :to (:result 0)) ecx) + :from (:argument 0) :to (:result 0)) ecx) (:ignore ecx) (:results (y :scs (any-reg descriptor-reg))) (:note "signed word to integer coercion") @@ -280,9 +238,9 @@ (:note "signed word to integer coercion") (:node-var node) (:generator 20 - (assert (not (location= x y))) + (aver (not (location= x y))) (let ((bignum (gen-label)) - (done (gen-label))) + (done (gen-label))) (inst mov y x) (inst shl y 1) (inst jmp :o bignum) @@ -290,8 +248,9 @@ (inst jmp :o bignum) (emit-label done) ;; KLUDGE: The sequence above leaves a DESCRIPTOR-REG Y in a - ;; non-descriptor state for a while. Does that matter? Does it matter in - ;; GENGC but not in GENCGC? Is this written down anywhere? + ;; non-descriptor state for a while. Does that matter? Does it + ;; matter in GENGC but not in GENCGC? Is this written down + ;; anywhere? ;; -- WHN 19990916 ;; ;; Also, the sequence above seems rather twisty. Why not something @@ -303,11 +262,11 @@ ;; emit-label done (assemble (*elsewhere*) - (emit-label bignum) - (with-fixed-allocation - (y bignum-type (+ bignum-digits-offset 1) node) - (storew x y bignum-digits-offset other-pointer-type)) - (inst jmp done))))) + (emit-label bignum) + (with-fixed-allocation + (y bignum-widetag (+ bignum-digits-offset 1) node) + (storew x y bignum-digits-offset other-pointer-lowtag)) + (inst jmp done))))) (define-move-vop move-from-signed :move (signed-reg) (descriptor-reg)) @@ -319,9 +278,9 @@ (:args (x :scs (signed-reg unsigned-reg) :target eax)) (:temporary (:sc unsigned-reg :offset eax-offset :from (:argument 0)) eax) (:temporary (:sc unsigned-reg :offset ebx-offset :to (:result 0) :target y) - ebx) + ebx) (:temporary (:sc unsigned-reg :offset ecx-offset - :from (:argument 0) :to (:result 0)) ecx) + :from (:argument 0) :to (:result 0)) ecx) (:ignore ecx) (:results (y :scs (any-reg descriptor-reg))) (:note "unsigned word to integer coercion") @@ -341,13 +300,13 @@ (:node-var node) (:note "unsigned word to integer coercion") (:generator 20 - (assert (not (location= x y))) - (assert (not (location= x alloc))) - (assert (not (location= y alloc))) + (aver (not (location= x y))) + (aver (not (location= x alloc))) + (aver (not (location= y alloc))) (let ((bignum (gen-label)) - (done (gen-label)) - (one-word-bignum (gen-label)) - (L1 (gen-label))) + (done (gen-label)) + (one-word-bignum (gen-label)) + (L1 (gen-label))) (inst test x #xe0000000) (inst jmp :nz bignum) ;; Fixnum. @@ -357,39 +316,39 @@ (emit-label done) (assemble (*elsewhere*) - (emit-label bignum) - ;; Note: As on the mips port, space for a two word bignum is - ;; always allocated and the header size is set to either one - ;; or two words as appropriate. - (inst jmp :ns one-word-bignum) - ;; Two word bignum. - (inst mov y (logior (ash (1- (+ bignum-digits-offset 2)) - sb!vm:type-bits) - bignum-type)) - (inst jmp L1) - (emit-label one-word-bignum) - (inst mov y (logior (ash (1- (+ bignum-digits-offset 1)) - sb!vm:type-bits) - bignum-type)) - (emit-label L1) - (pseudo-atomic - (allocation alloc (pad-data-block (+ bignum-digits-offset 2)) node) - (storew y alloc) - (inst lea y (make-ea :byte :base alloc :disp other-pointer-type)) - (storew x y bignum-digits-offset other-pointer-type)) - (inst jmp done))))) + (emit-label bignum) + ;; Note: As on the mips port, space for a two word bignum is + ;; always allocated and the header size is set to either one + ;; or two words as appropriate. + (inst jmp :ns one-word-bignum) + ;; two word bignum + (inst mov y (logior (ash (1- (+ bignum-digits-offset 2)) + n-widetag-bits) + bignum-widetag)) + (inst jmp L1) + (emit-label one-word-bignum) + (inst mov y (logior (ash (1- (+ bignum-digits-offset 1)) + n-widetag-bits) + bignum-widetag)) + (emit-label L1) + (pseudo-atomic + (allocation alloc (pad-data-block (+ bignum-digits-offset 2)) node) + (storew y alloc) + (inst lea y (make-ea :byte :base alloc :disp other-pointer-lowtag)) + (storew x y bignum-digits-offset other-pointer-lowtag)) + (inst jmp done))))) (define-move-vop move-from-unsigned :move (unsigned-reg) (descriptor-reg)) ;;; Move untagged numbers. (define-vop (word-move) (:args (x :scs (signed-reg unsigned-reg) :target y - :load-if (not (location= x y)))) + :load-if (not (location= x y)))) (:results (y :scs (signed-reg unsigned-reg) - :load-if - (not (or (location= x y) - (and (sc-is x signed-reg unsigned-reg) - (sc-is y signed-stack unsigned-stack)))))) + :load-if + (not (or (location= x y) + (and (sc-is x signed-reg unsigned-reg) + (sc-is y signed-stack unsigned-stack)))))) (:effects) (:affected) (:note "word integer move") @@ -399,9 +358,9 @@ (signed-reg unsigned-reg) (signed-reg unsigned-reg)) ;;; Move untagged number arguments/return-values. -(define-vop (move-word-argument) +(define-vop (move-word-arg) (:args (x :scs (signed-reg unsigned-reg) :target y) - (fp :scs (any-reg) :load-if (not (sc-is y sap-reg)))) + (fp :scs (any-reg) :load-if (not (sc-is y sap-reg)))) (:results (y)) (:note "word integer argument move") (:generator 0 @@ -410,12 +369,12 @@ (move y x)) ((signed-stack unsigned-stack) (if (= (tn-offset fp) esp-offset) - (storew x fp (tn-offset y)) ; c-call - (storew x fp (- (1+ (tn-offset y))))))))) -(define-move-vop move-word-argument :move-argument + (storew x fp (tn-offset y)) ; c-call + (storew x fp (frame-word-offset (tn-offset y)))))))) +(define-move-vop move-word-arg :move-arg (descriptor-reg any-reg signed-reg unsigned-reg) (signed-reg unsigned-reg)) -;;; Use standard MOVE-ARGUMENT and coercion to move an untagged number +;;; Use standard MOVE-ARG and coercion to move an untagged number ;;; to a descriptor passing location. -(define-move-vop move-argument :move-argument +(define-move-vop move-arg :move-arg (signed-reg unsigned-reg) (any-reg descriptor-reg))