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

📄 float.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 3 页
字号:
;;;; floating point support for the x86;;;; This software is part of the SBCL system. See the README file for;;;; more information.;;;;;;;; This software is derived from the CMU CL system, which was;;;; written at Carnegie Mellon University and released into the;;;; public domain. The software is in the public domain and is;;;; provided with absolutely no warranty. See the COPYING and CREDITS;;;; files for more information.(in-package "SB!VM")(macrolet ((ea-for-xf-desc (tn slot)             `(make-ea               :qword :base ,tn               :disp (- (* ,slot n-word-bytes)                        other-pointer-lowtag))))  (defun ea-for-df-desc (tn)    (ea-for-xf-desc tn double-float-value-slot))  ;; complex floats  (defun ea-for-csf-real-desc (tn)    (ea-for-xf-desc tn complex-single-float-real-slot))  (defun ea-for-csf-imag-desc (tn)    (ea-for-xf-desc tn complex-single-float-imag-slot))  (defun ea-for-cdf-real-desc (tn)    (ea-for-xf-desc tn complex-double-float-real-slot))  (defun ea-for-cdf-imag-desc (tn)    (ea-for-xf-desc tn complex-double-float-imag-slot)))(macrolet ((ea-for-xf-stack (tn kind)             (declare (ignore kind))             `(make-ea               :qword :base rbp-tn               :disp (- (* (+ (tn-offset ,tn) 1)                           n-word-bytes)))))  (defun ea-for-sf-stack (tn)    (ea-for-xf-stack tn :single))  (defun ea-for-df-stack (tn)    (ea-for-xf-stack tn :double)));;; complex float stack EAs(macrolet ((ea-for-cxf-stack (tn kind slot &optional base)             (declare (ignore kind))             `(make-ea               :qword :base ,base               :disp (- (* (+ (tn-offset ,tn)                              (* 1 (ecase ,slot (:real 1) (:imag 2))))                           n-word-bytes)))))  (defun ea-for-csf-real-stack (tn &optional (base rbp-tn))    (ea-for-cxf-stack tn :single :real base))  (defun ea-for-csf-imag-stack (tn &optional (base rbp-tn))    (ea-for-cxf-stack tn :single :imag base))  (defun ea-for-cdf-real-stack (tn &optional (base rbp-tn))    (ea-for-cxf-stack tn :double :real base))  (defun ea-for-cdf-imag-stack (tn &optional (base rbp-tn))    (ea-for-cxf-stack tn :double :imag base)));;;; move functions;;; X is source, Y is destination.(define-move-fun (load-fp-zero 1) (vop x y)  ((fp-single-zero) (single-reg)   (fp-double-zero) (double-reg))  (identity x)  (sc-case y    (single-reg (inst xorps y y))    (double-reg (inst xorpd y y))))(define-move-fun (load-single 2) (vop x y)  ((single-stack) (single-reg))  (inst movss y (ea-for-sf-stack x)))(define-move-fun (store-single 2) (vop x y)  ((single-reg) (single-stack))  (inst movss (ea-for-sf-stack y) x))(define-move-fun (load-double 2) (vop x y)  ((double-stack) (double-reg))  (inst movsd y (ea-for-df-stack x)))(define-move-fun (store-double 2) (vop x y)  ((double-reg) (double-stack))  (inst movsd  (ea-for-df-stack y) x))(eval-when (:compile-toplevel :execute)  (setf *read-default-float-format* 'single-float));;;; complex float move functions(defun complex-single-reg-real-tn (x)  (make-random-tn :kind :normal :sc (sc-or-lose 'single-reg)                  :offset (tn-offset x)))(defun complex-single-reg-imag-tn (x)  (make-random-tn :kind :normal :sc (sc-or-lose 'single-reg)                  :offset (1+ (tn-offset x))))(defun complex-double-reg-real-tn (x)  (make-random-tn :kind :normal :sc (sc-or-lose 'double-reg)                  :offset (tn-offset x)))(defun complex-double-reg-imag-tn (x)  (make-random-tn :kind :normal :sc (sc-or-lose 'double-reg)                  :offset (1+ (tn-offset x))));;; X is source, Y is destination.(define-move-fun (load-complex-single 2) (vop x y)  ((complex-single-stack) (complex-single-reg))  (let ((real-tn (complex-single-reg-real-tn y)))    (inst movss real-tn (ea-for-csf-real-stack x)))  (let ((imag-tn (complex-single-reg-imag-tn y)))    (inst movss imag-tn (ea-for-csf-imag-stack x))))(define-move-fun (store-complex-single 2) (vop x y)  ((complex-single-reg) (complex-single-stack))  (let ((real-tn (complex-single-reg-real-tn x))        (imag-tn (complex-single-reg-imag-tn x)))    (inst movss (ea-for-csf-real-stack y) real-tn)    (inst movss (ea-for-csf-imag-stack y) imag-tn)))(define-move-fun (load-complex-double 2) (vop x y)  ((complex-double-stack) (complex-double-reg))  (let ((real-tn (complex-double-reg-real-tn y)))    (inst movsd real-tn (ea-for-cdf-real-stack x)))  (let ((imag-tn (complex-double-reg-imag-tn y)))    (inst movsd imag-tn (ea-for-cdf-imag-stack x))))(define-move-fun (store-complex-double 2) (vop x y)  ((complex-double-reg) (complex-double-stack))  (let ((real-tn (complex-double-reg-real-tn x))        (imag-tn (complex-double-reg-imag-tn x)))    (inst movsd (ea-for-cdf-real-stack y) real-tn)    (inst movsd (ea-for-cdf-imag-stack y) imag-tn)));;;; move VOPs;;; float register to register moves(macrolet ((frob (vop sc)             `(progn                (define-vop (,vop)                  (:args (x :scs (,sc)                            :target y                            :load-if (not (location= x y))))                  (:results (y :scs (,sc)                               :load-if (not (location= x y))))                  (:note "float move")                  (:generator 0                    (unless (location= y x)                      (inst movq y x))))                (define-move-vop ,vop :move (,sc) (,sc)))))  (frob single-move single-reg)  (frob double-move double-reg));;; complex float register to register moves(define-vop (complex-float-move)  (:args (x :target y :load-if (not (location= x y))))  (:results (y :load-if (not (location= x y))))  (:note "complex float move")  (:generator 0     (unless (location= x y)       ;; Note the complex-float-regs are aligned to every second       ;; float register so there is not need to worry about overlap.       ;; (It would be better to put the imagpart in the top half of the       ;; register, or something, but let's worry about that later)       (let ((x-real (complex-single-reg-real-tn x))             (y-real (complex-single-reg-real-tn y)))         (inst movq y-real x-real))       (let ((x-imag (complex-single-reg-imag-tn x))             (y-imag (complex-single-reg-imag-tn y)))         (inst movq y-imag x-imag)))))(define-vop (complex-single-move complex-float-move)  (:args (x :scs (complex-single-reg) :target y            :load-if (not (location= x y))))  (:results (y :scs (complex-single-reg) :load-if (not (location= x y)))))(define-move-vop complex-single-move :move  (complex-single-reg) (complex-single-reg))(define-vop (complex-double-move complex-float-move)  (:args (x :scs (complex-double-reg)            :target y :load-if (not (location= x y))))  (:results (y :scs (complex-double-reg) :load-if (not (location= x y)))))(define-move-vop complex-double-move :move  (complex-double-reg) (complex-double-reg));;; Move from float to a descriptor reg. allocating a new float;;; object in the process.(define-vop (move-from-single)  (:args (x :scs (single-reg) :to :save))  (:results (y :scs (descriptor-reg)))  (:note "float to pointer coercion")  (:generator 4    (inst movd y x)    (inst shl y 32)    (inst or y single-float-widetag)))(define-move-vop move-from-single :move  (single-reg) (descriptor-reg))(define-vop (move-from-double)  (:args (x :scs (double-reg) :to :save))  (:results (y :scs (descriptor-reg)))  (:node-var node)  (:note "float to pointer coercion")  (:generator 13     (with-fixed-allocation (y                             double-float-widetag                             double-float-size                             node)       (inst movsd (ea-for-df-desc y) x))))(define-move-vop move-from-double :move  (double-reg) (descriptor-reg));;; Move from a descriptor to a float register.(define-vop (move-to-single)  (:args (x :scs (descriptor-reg) :target tmp))  (:temporary (:sc unsigned-reg) tmp)  (:results (y :scs (single-reg)))  (:note "pointer to float coercion")  (:generator 2    (move tmp x)    (inst shr tmp 32)    (inst movd y tmp)))(define-move-vop move-to-single :move (descriptor-reg) (single-reg))(define-vop (move-to-double)  (:args (x :scs (descriptor-reg)))  (:results (y :scs (double-reg)))  (:note "pointer to float coercion")  (:generator 2    (inst movsd y (ea-for-df-desc x))))(define-move-vop move-to-double :move (descriptor-reg) (double-reg));;; Move from complex float to a descriptor reg. allocating a new;;; complex float object in the process.(define-vop (move-from-complex-single)  (:args (x :scs (complex-single-reg) :to :save))  (:results (y :scs (descriptor-reg)))  (: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)))         (inst movss (ea-for-csf-real-desc y) real-tn))       (let ((imag-tn (complex-single-reg-imag-tn x)))         (inst movss (ea-for-csf-imag-desc y) imag-tn)))))(define-move-vop move-from-complex-single :move  (complex-single-reg) (descriptor-reg))(define-vop (move-from-complex-double)  (:args (x :scs (complex-double-reg) :to :save))  (:results (y :scs (descriptor-reg)))  (:node-var node)  (:note "complex float to pointer coercion")  (:generator 13     (with-fixed-allocation (y                             complex-double-float-widetag                             complex-double-float-size                             node)       (let ((real-tn (complex-double-reg-real-tn x)))         (inst movsd (ea-for-cdf-real-desc y) real-tn))       (let ((imag-tn (complex-double-reg-imag-tn x)))         (inst movsd (ea-for-cdf-imag-desc y) imag-tn)))))(define-move-vop move-from-complex-double :move  (complex-double-reg) (descriptor-reg));;; Move from a descriptor to a complex float register.(macrolet ((frob (name sc format)             `(progn                (define-vop (,name)                  (:args (x :scs (descriptor-reg)))                  (:results (y :scs (,sc)))                  (:note "pointer to complex float coercion")                  (:generator 2                    (let ((real-tn (complex-double-reg-real-tn y)))                      ,@(ecase                         format                         (:single                          '((inst movss real-tn (ea-for-csf-real-desc x))))                         (:double                          '((inst movsd real-tn (ea-for-cdf-real-desc x))))))                    (let ((imag-tn (complex-double-reg-imag-tn y)))                      ,@(ecase                         format                         (:single                          '((inst movss imag-tn (ea-for-csf-imag-desc x))))                         (:double                          '((inst movsd imag-tn (ea-for-cdf-imag-desc x))))))))                (define-move-vop ,name :move (descriptor-reg) (,sc)))))  (frob move-to-complex-single complex-single-reg :single)  (frob move-to-complex-double complex-double-reg :double));;;; the move argument vops;;;;;;;; Note these are also used to stuff fp numbers onto the c-call;;;; stack so the order is different than the lisp-stack.;;; the general 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 "float argument move")                  (:generator ,(case format (:single 2) (:double 3) )                    (sc-case y                      (,sc                       (unless (location= x y)                         (inst movq y x)))                      (,stack-sc

⌨️ 快捷键说明

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