-;;;; the x86 VM definition of operand loading/saving and the MOVE vop
+;;;; the x86-64 VM definition of operand loading/saving and the MOVE vop
;;;; This software is part of the SBCL system. See the README file for
;;;; more information.
(in-package "SB!VM")
+(defun make-byte-tn (tn)
+ (aver (sc-is tn any-reg descriptor-reg unsigned-reg signed-reg))
+ (make-random-tn :kind :normal
+ :sc (sc-or-lose 'byte-reg)
+ :offset (tn-offset tn)))
+
+(defun make-dword-tn (tn)
+ (aver (sc-is tn any-reg descriptor-reg character-reg
+ unsigned-reg signed-reg))
+ (make-random-tn :kind :normal
+ :sc (sc-or-lose 'dword-reg)
+ :offset (tn-offset tn)))
+
+(defun zeroize (tn)
+ (let ((offset (tn-offset tn)))
+ ;; Using the 32-bit instruction accomplishes the same thing and is
+ ;; one byte shorter.
+ (if (<= offset edi-offset)
+ (let ((tn (make-random-tn :kind :normal
+ :sc (sc-or-lose 'dword-reg)
+ :offset offset)))
+ (inst xor tn tn))
+ (inst xor tn tn))))
+
(define-move-fun (load-immediate 1) (vop x y)
((immediate)
(any-reg descriptor-reg))
(etypecase val
(integer
(if (zerop val)
- (inst xor y y)
+ (zeroize y)
(inst mov y (fixnumize val))))
(symbol
(load-symbol y val))
(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)
+ (zeroize y)
+ (inst mov y val))))
(define-move-fun (load-character 1) (vop x y)
((immediate) (character-reg))
(etypecase val
(integer
(if (and (zerop val) (sc-is y any-reg descriptor-reg))
- (inst xor y y)
+ (zeroize y)
(move-immediate y (fixnumize val) temp)))
(symbol
(inst mov y (+ nil-value (static-symbol-offset val))))
(let ((val (tn-value x)))
(etypecase val
((integer 0 0)
- (inst xor y y))
+ (zeroize y))
((or (signed-byte 29) (unsigned-byte 29))
(inst mov y (fixnumize val)))
(integer
(aver (not (location= x y)))
(let ((bignum (gen-label))
(done (gen-label)))
- (inst mov y x)
;; We can't do the overflow check with SHL Y, 3, since the
;; state of the overflow flag is only reliably set when
;; shifting by 1. There used to be code here for doing "shift
;; we can just do a straight multiply instead of trying to
;; optimize it to a shift. This is both faster and smaller.
;; -- JES, 2006-07-08
- (inst imul y 8)
+ (inst imul y x (ash 1 n-fixnum-tag-bits))
(inst jmp :o bignum)
(emit-label done)