(in-package "SB!VM")
\f
(macrolet ((ea-for-xf-desc (tn slot)
- `(make-ea
- :dword :base ,tn
- :disp (- (* ,slot n-word-bytes)
- other-pointer-lowtag))))
+ `(make-ea-for-object-slot ,tn ,slot other-pointer-lowtag)))
(defun ea-for-sf-desc (tn)
(ea-for-xf-desc tn single-float-value-slot))
(defun ea-for-df-desc (tn)
#!+long-float 'long-float #!-long-float 'double-float))
(define-move-fun (load-fp-constant 2) (vop x y)
((fp-constant) (single-reg double-reg #!+long-float long-reg))
- (let ((value (sb!c::constant-value (sb!c::tn-leaf x))))
+ (let ((value (tn-value x)))
(with-empty-tn@fp-top(y)
- (cond ((zerop value)
+ (cond ((or (eql value 0f0) (eql value 0d0) #!+long-float (eql value 0l0))
(inst fldz))
((= value 1e0)
(inst fld1))
+ #!+long-float
((= value (coerce pi *read-default-float-format*))
(inst fldpi))
+ #!+long-float
((= value (log 10e0 2e0))
(inst fldl2t))
+ #!+long-float
((= value (log 2.718281828459045235360287471352662e0 2e0))
(inst fldl2e))
+ #!+long-float
((= value (log 2e0 10e0))
(inst fldlg2))
+ #!+long-float
((= value (log 2e0 2.718281828459045235360287471352662e0))
(inst fldln2))
(t (warn "ignoring bogus i387 constant ~A" value))))))
+
+(define-move-fun (load-fp-immediate 2) (vop x y)
+ ((fp-single-immediate) (single-reg)
+ (fp-double-immediate) (double-reg))
+ (let ((value (register-inline-constant (tn-value x))))
+ (with-empty-tn@fp-top(y)
+ (sc-case y
+ (single-reg
+ (inst fld value))
+ (double-reg
+ (inst fldd value))))))
(eval-when (:compile-toplevel :execute)
(setf *read-default-float-format* 'single-float))
\f
(:node-var node)
(:note "complex float to pointer coercion")
(:generator 13
- (with-fixed-allocation (y
- complex-single-float-widetag
- complex-single-float-size
- node)
- (let ((real-tn (complex-single-reg-real-tn x)))
- (with-tn@fp-top(real-tn)
- (inst fst (ea-for-csf-real-desc y))))
- (let ((imag-tn (complex-single-reg-imag-tn x)))
- (with-tn@fp-top(imag-tn)
- (inst fst (ea-for-csf-imag-desc y)))))))
+ (with-fixed-allocation (y
+ complex-single-float-widetag
+ complex-single-float-size
+ node)
+ (let ((real-tn (complex-single-reg-real-tn x)))
+ (with-tn@fp-top(real-tn)
+ (inst fst (ea-for-csf-real-desc y))))
+ (let ((imag-tn (complex-single-reg-imag-tn x)))
+ (with-tn@fp-top(imag-tn)
+ (inst fst (ea-for-csf-imag-desc y)))))))
(define-move-vop move-from-complex-single :move
(complex-single-reg) (descriptor-reg))
(define-vop (=/float)
(:args (x) (y))
(:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
- (:conditional)
- (:info target not-p)
+ (:conditional :e)
(:policy :fast-safe)
(:vop-var vop)
(:save-p :compute-only)
(inst fxch x)))
(inst fnstsw) ; status word to ax
(inst and ah-tn #x45) ; C3 C2 C0
- (inst cmp ah-tn #x40)
- (inst jmp (if not-p :ne :e) target)))
+ (inst cmp ah-tn #x40)))
(define-vop (=/single-float =/float)
(:translate =)
(:arg-types single-float single-float)
(:temporary (:sc single-reg :offset fr0-offset :from :eval) fr0)
(:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
- (:conditional)
- (:info target not-p)
+ (:conditional :e)
(:policy :fast-safe)
(:note "inline float comparison")
(:ignore temp)
(inst fcom (ea-for-sf-desc y)))))
(inst fnstsw) ; status word to ax
(inst and ah-tn #x45) ; C3 C2 C0
- (inst cmp ah-tn #x01)))
- (inst jmp (if not-p :ne :e) target)))
+ (inst cmp ah-tn #x01)))))
(define-vop (<double-float)
(:translate <)
(:arg-types double-float double-float)
(:temporary (:sc double-reg :offset fr0-offset :from :eval) fr0)
(:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
- (:conditional)
- (:info target not-p)
+ (:conditional :e)
(:policy :fast-safe)
(:note "inline float comparison")
(:ignore temp)
(inst fcomd (ea-for-df-desc y)))))
(inst fnstsw) ; status word to ax
(inst and ah-tn #x45) ; C3 C2 C0
- (inst cmp ah-tn #x01)))
- (inst jmp (if not-p :ne :e) target)))
+ (inst cmp ah-tn #x01)))))
#!+long-float
(define-vop (<long-float)
(y :scs (long-reg)))
(:arg-types long-float long-float)
(:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
- (:conditional)
- (:info target not-p)
+ (:conditional :e)
(:policy :fast-safe)
(:note "inline float comparison")
(:ignore temp)
(inst fcomd x)
(inst fxch y)
(inst fnstsw) ; status word to ax
- (inst and ah-tn #x45))) ; C3 C2 C0
- (inst jmp (if not-p :ne :e) target)))
+ (inst and ah-tn #x45))))) ; C3 C2 C0
+
(define-vop (>single-float)
(:translate >)
(:arg-types single-float single-float)
(:temporary (:sc single-reg :offset fr0-offset :from :eval) fr0)
(:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
- (:conditional)
- (:info target not-p)
+ (:conditional :e)
(:policy :fast-safe)
(:note "inline float comparison")
(:ignore temp)
(inst fcom (ea-for-sf-stack y))
(inst fcom (ea-for-sf-desc y)))))
(inst fnstsw) ; status word to ax
- (inst and ah-tn #x45)))
- (inst jmp (if not-p :ne :e) target)))
+ (inst and ah-tn #x45)))))
(define-vop (>double-float)
(:translate >)
(:arg-types double-float double-float)
(:temporary (:sc double-reg :offset fr0-offset :from :eval) fr0)
(:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
- (:conditional)
- (:info target not-p)
+ (:conditional :e)
(:policy :fast-safe)
(:note "inline float comparison")
(:ignore temp)
(inst fcomd (ea-for-df-stack y))
(inst fcomd (ea-for-df-desc y)))))
(inst fnstsw) ; status word to ax
- (inst and ah-tn #x45)))
- (inst jmp (if not-p :ne :e) target)))
+ (inst and ah-tn #x45)))))
#!+long-float
(define-vop (>long-float)
(y :scs (long-reg)))
(:arg-types long-float long-float)
(:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
- (:conditional)
- (:info target not-p)
+ (:conditional :e)
(:policy :fast-safe)
(:note "inline float comparison")
(:ignore temp)
(inst fcomd y)
(inst fxch x)
(inst fnstsw) ; status word to ax
- (inst and ah-tn #x45)))
- (inst jmp (if not-p :ne :e) target)))
+ (inst and ah-tn #x45)))))
;;; Comparisons with 0 can use the FTST instruction.
(define-vop (float-test)
(:args (x))
(:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
- (:conditional)
- (:info target not-p y)
+ (:conditional :e)
+ (:info y)
(:variant-vars code)
(:policy :fast-safe)
(:vop-var vop)
(inst fnstsw) ; status word to ax
(inst and ah-tn #x45) ; C3 C2 C0
(unless (zerop code)
- (inst cmp ah-tn code))
- (inst jmp (if not-p :ne :e) target)))
+ (inst cmp ah-tn code))))
(define-vop (=0/single-float float-test)
(:translate =)
(inst mov y stack-temp)))
,@(unless round-p
'((inst fldcw scw)))))))))
- (frob %unary-truncate single-reg single-float nil)
- (frob %unary-truncate double-reg double-float nil)
+ (frob %unary-truncate/single-float single-reg single-float nil)
+ (frob %unary-truncate/double-float double-reg double-float nil)
#!+long-float
- (frob %unary-truncate long-reg long-float nil)
+ (frob %unary-truncate/long-float long-reg long-float nil)
(frob %unary-round single-reg single-float t)
(frob %unary-round double-reg double-float t)
#!+long-float
(inst add esp-tn 4)
,@(unless round-p
'((inst fldcw scw)))))))
- (frob %unary-truncate single-reg single-float nil)
- (frob %unary-truncate double-reg double-float nil)
+ (frob %unary-truncate/single-float single-reg single-float nil)
+ (frob %unary-truncate/double-float double-reg double-float nil)
#!+long-float
- (frob %unary-truncate long-reg long-float nil)
+ (frob %unary-truncate/long-float long-reg long-float nil)
(frob %unary-round single-reg single-float t)
(frob %unary-round double-reg double-float t)
#!+long-float
:disp (frame-byte-offset (tn-offset temp)))))
(descriptor-reg
(inst movsx exp-bits
- (make-ea :word :base float
- :disp (- (* (+ 2 long-float-value-slot)
- n-word-bytes)
- other-pointer-lowtag)))))))
+ (make-ea-for-object-slot float (+ 2 long-float-value-slot)
+ other-pointer-lowtag :word))))))
#!+long-float
(define-vop (long-float-high-bits)