#!+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 ((or (eql value 0f0) (eql value 0d0) #!+long-float (eql value 0l0))
(inst fldz))
((= 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))
(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
(:args (x :scs (double-reg) :target fr0))
(:temporary (:sc double-reg :offset fr0-offset
:from :argument :to :result) fr0)
+ ;; FIXME: make that an arbitrary location and
+ ;; FXCH only when range reduction needed
+ (:temporary (:sc double-reg :offset fr1-offset
+ :from :argument :to :result) fr1)
(:temporary (:sc unsigned-reg :offset eax-offset
:from :argument :to :result) eax)
(:results (y :scs (double-reg)))
(:save-p :compute-only)
(:ignore eax)
(:generator 5
- (note-this-location vop :internal-error)
- (unless (zerop (tn-offset x))
- (inst fxch x) ; x to top of stack
- (unless (location= x y)
- (inst fst x))) ; maybe save it
- (inst ,op)
- (inst fnstsw) ; status word to ax
- (inst and ah-tn #x04) ; C2
- (inst jmp :z DONE)
- ;; Else x was out of range so reduce it; ST0 is unchanged.
- (inst fstp fr0) ; Load 0.0
- (inst fldz)
- DONE
- (unless (zerop (tn-offset y))
- (inst fstd y))))))
+ (let ((DONE (gen-label))
+ (REDUCE (gen-label))
+ (REDUCE-LOOP (gen-label)))
+ (note-this-location vop :internal-error)
+ (unless (zerop (tn-offset x))
+ (inst fxch x) ; x to top of stack
+ (unless (location= x y)
+ (inst fst x))) ; maybe save it
+ (inst ,op)
+ (inst fnstsw) ; status word to ax
+ (inst and ah-tn #x04) ; C2
+ (inst jmp :nz REDUCE)
+ (emit-label DONE)
+ (unless (zerop (tn-offset y))
+ (inst fstd y))
+ (assemble (*elsewhere*)
+ (emit-label REDUCE)
+ ;; Else x was out of range so reduce it; ST0 is unchanged.
+ (with-empty-tn@fp-top (fr1)
+ (inst fldpi)
+ (inst fadd fr0))
+ (emit-label REDUCE-LOOP)
+ (inst fprem1)
+ (inst fnstsw)
+ (inst and ah-tn #x04)
+ (inst jmp :nz REDUCE-LOOP)
+ (inst ,op)
+ (inst jmp DONE)))))))
(frob fsin %sin fsin)
(frob fcos %cos fcos))
:sc (sc-or-lose 'double-reg)
:offset (- (tn-offset x) 2)))))
(inst fptan)
- (inst fnstsw) ; status word to ax
- (inst and ah-tn #x04) ; C2
- (inst jmp :z DONE)
- ;; Else x was out of range so load 0.0
- (inst fxch fr1)
+ (let ((REDUCE (gen-label))
+ (REDUCE-LOOP (gen-label)))
+ (inst fnstsw) ; status word to ax
+ (inst and ah-tn #x04) ; C2
+ (inst jmp :nz REDUCE)
+ (assemble (*elsewhere*)
+ (emit-label REDUCE)
+ ;; Else x was out of range so reduce it; ST0 is unchanged.
+ (with-empty-tn@fp-top (fr1)
+ (inst fldpi)
+ (inst fadd fr0))
+ (emit-label REDUCE-LOOP)
+ (inst fprem1)
+ (inst fnstsw)
+ (inst and ah-tn #x04)
+ (inst jmp :nz REDUCE-LOOP)
+ (inst fptan)
+ (inst jmp DONE)))
DONE
;; Result is in fr1
(case (tn-offset y)