1.0.29.54: Inline unboxed constants on x86[-64]
[sbcl.git] / src / compiler / x86 / float.lisp
index fd69f80..bde111a 100644 (file)
         #!+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 =)