⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 float.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 3 页
字号:
                       (if (= (tn-offset fp) esp-offset)                           (let* ((offset (* (tn-offset y) n-word-bytes))                                  (ea (make-ea :dword :base fp :disp offset)))                             ,@(ecase format                                      (:single '((inst movss ea x)))                                      (:double '((inst movsd ea x)))))                           (let ((ea (make-ea                                      :dword :base fp                                      :disp (- (* (1+ (tn-offset y))                                                  n-word-bytes)))))                             ,@(ecase format                                 (:single '((inst movss ea x)))                                 (:double '((inst movsd ea x))))))))))                (define-move-vop ,name :move-arg                  (,sc descriptor-reg) (,sc)))))  (frob move-single-float-arg single-reg single-stack :single)  (frob move-double-float-arg double-reg double-stack :double));;;; complex float MOVE-ARG VOP(macrolet ((frob (name sc stack-sc format)             `(progn                (define-vop (,name)                  (:args (x :scs (,sc) :target y)                         (fp :scs (any-reg)                             :load-if (not (sc-is y ,sc))))                  (:results (y))                  (:note "complex float argument move")                  (:generator ,(ecase format (:single 2) (:double 3))                    (sc-case y                      (,sc                       (unless (location= x y)                         (let ((x-real (complex-double-reg-real-tn x))                               (y-real (complex-double-reg-real-tn y)))                           (inst movsd y-real x-real))                         (let ((x-imag (complex-double-reg-imag-tn x))                               (y-imag (complex-double-reg-imag-tn y)))                           (inst movsd y-imag x-imag))))                      (,stack-sc                       (let ((real-tn (complex-double-reg-real-tn x)))                         ,@(ecase format                                  (:single                                   '((inst movss                                      (ea-for-csf-real-stack y fp)                                      real-tn)))                                  (:double                                   '((inst movsd                                      (ea-for-cdf-real-stack y fp)                                      real-tn)))))                       (let ((imag-tn (complex-double-reg-imag-tn x)))                         ,@(ecase format                                  (:single                                   '((inst movss                                      (ea-for-csf-imag-stack y fp) imag-tn)))                                  (:double                                   '((inst movsd                                      (ea-for-cdf-imag-stack y fp) imag-tn)))))))))                (define-move-vop ,name :move-arg                  (,sc descriptor-reg) (,sc)))))  (frob move-complex-single-float-arg        complex-single-reg complex-single-stack :single)  (frob move-complex-double-float-arg        complex-double-reg complex-double-stack :double))(define-move-vop move-arg :move-arg  (single-reg double-reg   complex-single-reg complex-double-reg)  (descriptor-reg));;;; arithmetic VOPs(define-vop (float-op)  (:args (x) (y))  (:results (r))  (:policy :fast-safe)  (:note "inline float arithmetic")  (:vop-var vop)  (:save-p :compute-only))(macrolet ((frob (name sc ptype)             `(define-vop (,name float-op)                (:args (x :scs (,sc) :target r)                       (y :scs (,sc)))                (:results (r :scs (,sc)))                (:arg-types ,ptype ,ptype)                (:result-types ,ptype))))  (frob single-float-op single-reg single-float)  (frob double-float-op double-reg double-float))(macrolet ((generate (movinst opinst commutative)             `(progn                (cond                  ((location= x r)                   (inst ,opinst x y))                  ((and ,commutative (location= y r))                   (inst ,opinst y x))                  ((not (location= r y))                   (inst ,movinst r x)                   (inst ,opinst r y))                  (t                   (inst ,movinst tmp x)                   (inst ,opinst tmp y)                   (inst ,movinst r tmp)))))           (frob (op sinst sname scost dinst dname dcost commutative)             `(progn                (define-vop (,sname single-float-op)                    (:translate ,op)                  (:temporary (:sc single-reg) tmp)                  (:generator ,scost                    (generate movss ,sinst ,commutative)))                (define-vop (,dname double-float-op)                  (:translate ,op)                  (:temporary (:sc single-reg) tmp)                  (:generator ,dcost                    (generate movsd ,dinst ,commutative))))))  (frob + addss +/single-float 2 addsd +/double-float 2 t)  (frob - subss -/single-float 2 subsd -/double-float 2 nil)  (frob * mulss */single-float 4 mulsd */double-float 5 t)  (frob / divss //single-float 12 divsd //double-float 19 nil))(define-vop (fsqrt)  (:args (x :scs (double-reg)))  (:results (y :scs (double-reg)))  (:translate %sqrt)  (:policy :fast-safe)  (:arg-types double-float)  (:result-types double-float)  (:note "inline float arithmetic")  (:vop-var vop)  (:save-p :compute-only)  (:generator 1     (note-this-location vop :internal-error)     (inst sqrtsd y x)))(macrolet ((frob ((name translate sc type) &body body)             `(define-vop (,name)                  (:args (x :scs (,sc)))                (:results (y :scs (,sc)))                (:translate ,translate)                (:policy :fast-safe)                (:arg-types ,type)                (:result-types ,type)                (:temporary (:sc any-reg) hex8)                (:temporary                 (:sc ,sc) xmm)                (:note "inline float arithmetic")                (:vop-var vop)                (:save-p :compute-only)                (:generator 1                            (note-this-location vop :internal-error)                            ;; we should be able to do this better.  what we                            ;; really would like to do is use the target as the                            ;; temp whenever it's not also the source                            (unless (location= x y)                              (inst movq y x))                            ,@body))))  (frob (%negate/double-float %negate double-reg double-float)        (inst lea hex8 (make-ea :qword :disp 1))        (inst ror hex8 1)               ; #x8000000000000000        (inst movd xmm hex8)        (inst xorpd y xmm))  (frob (%negate/single-float %negate single-reg single-float)        (inst lea hex8 (make-ea :qword :disp 1))        (inst rol hex8 31)        (inst movd xmm hex8)        (inst xorps y xmm))  (frob (abs/double-float abs  double-reg double-float)        (inst mov hex8 -1)        (inst shr hex8 1)        (inst movd xmm hex8)        (inst andpd y xmm))  (frob (abs/single-float abs  single-reg single-float)        (inst mov hex8 -1)        (inst shr hex8 33)        (inst movd xmm hex8)        (inst andps y xmm)));;;; comparison(define-vop (float-compare)  (:conditional)  (:info target not-p)  (:policy :fast-safe)  (:vop-var vop)  (:save-p :compute-only)  (:note "inline float comparison"));;; comiss and comisd can cope with one or other arg in memory: we;;; could (should, indeed) extend these to cope with descriptor args;;; and stack args(define-vop (single-float-compare float-compare)  (:args (x :scs (single-reg)) (y :scs (single-reg)))  (:conditional)  (:arg-types single-float single-float))(define-vop (double-float-compare float-compare)  (:args (x :scs (double-reg)) (y :scs (double-reg)))  (:conditional)  (:arg-types double-float double-float))(define-vop (=/single-float single-float-compare)    (:translate =)  (:info target not-p)  (:vop-var vop)  (:generator 3    (note-this-location vop :internal-error)    (inst comiss x y)    ;; if PF&CF, there was a NaN involved => not equal    ;; otherwise, ZF => equal    (cond (not-p           (inst jmp :p target)           (inst jmp :ne target))          (t           (let ((not-lab (gen-label)))             (inst jmp :p not-lab)             (inst jmp :e target)             (emit-label not-lab))))))(define-vop (=/double-float double-float-compare)    (:translate =)  (:info target not-p)  (:vop-var vop)  (:generator 3    (note-this-location vop :internal-error)    (inst comisd x y)    (cond (not-p           (inst jmp :p target)           (inst jmp :ne target))          (t           (let ((not-lab (gen-label)))             (inst jmp :p not-lab)             (inst jmp :e target)             (emit-label not-lab))))))(define-vop (<double-float double-float-compare)  (:translate <)  (:info target not-p)  (:generator 3    (inst comisd x y)    (cond (not-p           (inst jmp :p target)           (inst jmp :nc target))          (t           (let ((not-lab (gen-label)))             (inst jmp :p not-lab)             (inst jmp :c target)             (emit-label not-lab))))))(define-vop (<single-float single-float-compare)  (:translate <)  (:info target not-p)  (:generator 3    (inst comiss x y)    (cond (not-p           (inst jmp :p target)           (inst jmp :nc target))          (t           (let ((not-lab (gen-label)))             (inst jmp :p not-lab)             (inst jmp :c target)             (emit-label not-lab))))))(define-vop (>double-float double-float-compare)  (:translate >)  (:info target not-p)  (:generator 3    (inst comisd x y)    (cond (not-p           (inst jmp :p target)           (inst jmp :na target))          (t           (let ((not-lab (gen-label)))             (inst jmp :p not-lab)             (inst jmp :a target)             (emit-label not-lab))))))(define-vop (>single-float single-float-compare)  (:translate >)  (:info target not-p)  (:generator 3    (inst comiss x y)    (cond (not-p           (inst jmp :p target)           (inst jmp :na target))          (t           (let ((not-lab (gen-label)))             (inst jmp :p not-lab)             (inst jmp :a target)             (emit-label not-lab))))));;;; conversion(macrolet ((frob (name translate inst to-sc to-type)             `(define-vop (,name)                (:args (x :scs (signed-stack signed-reg) :target temp))                (:temporary (:sc signed-stack) temp)                (:results (y :scs (,to-sc)))                (:arg-types signed-num)                (:result-types ,to-type)                (:policy :fast-safe)                (:note "inline float coercion")                (:translate ,translate)                (:vop-var vop)                (:save-p :compute-only)                (:generator 5                  (sc-case x                    (signed-reg                     (inst mov temp x)                     (note-this-location vop :internal-error)                     (inst ,inst y temp))                    (signed-stack                     (note-this-location vop :internal-error)                     (inst ,inst y x)))))))  (frob %single-float/signed %single-float cvtsi2ss single-reg single-float)  (frob %double-float/signed %double-float cvtsi2sd double-reg double-float))(macrolet ((frob (name translate inst from-sc from-type to-sc to-type)             `(define-vop (,name)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -