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

📄 float.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 5 页
字号:
;;;; floating point support for the Sparc;;;; 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");;;; float move functions(define-move-fun (load-single 1) (vop x y)  ((single-stack) (single-reg))  (inst ldf y (current-nfp-tn vop) (* (tn-offset x) n-word-bytes)))(define-move-fun (store-single 1) (vop x y)  ((single-reg) (single-stack))  (inst stf x (current-nfp-tn vop) (* (tn-offset y) n-word-bytes)))(define-move-fun (load-double 2) (vop x y)  ((double-stack) (double-reg))  (let ((nfp (current-nfp-tn vop))        (offset (* (tn-offset x) n-word-bytes)))    (inst lddf y nfp offset)))(define-move-fun (store-double 2) (vop x y)  ((double-reg) (double-stack))  (let ((nfp (current-nfp-tn vop))        (offset (* (tn-offset y) n-word-bytes)))    (inst stdf x nfp offset)));;; The offset may be an integer or a TN in which case it will be;;; temporarily modified but is restored if restore-offset is true.(defun load-long-reg (reg base offset &optional (restore-offset t))  (cond    ((member :sparc-v9 *backend-subfeatures*)     (inst ldqf reg base offset))    (t     (let ((reg0 (make-random-tn :kind :normal                                 :sc (sc-or-lose 'double-reg)                                 :offset (tn-offset reg)))           (reg2 (make-random-tn :kind :normal                                 :sc (sc-or-lose 'double-reg)                                 :offset (+ 2 (tn-offset reg)))))       (cond ((integerp offset)              (inst lddf reg0 base offset)              (inst lddf reg2 base (+ offset (* 2 n-word-bytes))))             (t              (inst lddf reg0 base offset)              (inst add offset (* 2 n-word-bytes))              (inst lddf reg2 base offset)              (when restore-offset                (inst sub offset (* 2 n-word-bytes)))))))))#!+long-float(define-move-fun (load-long 2) (vop x y)  ((long-stack) (long-reg))  (let ((nfp (current-nfp-tn vop))        (offset (* (tn-offset x) n-word-bytes)))    (load-long-reg y nfp offset)));;; The offset may be an integer or a TN in which case it will be;;; temporarily modified but is restored if restore-offset is true.(defun store-long-reg (reg base offset &optional (restore-offset t))  (cond    ((member :sparc-v9 *backend-subfeatures*)     (inst stqf reg base offset))    (t     (let ((reg0 (make-random-tn :kind :normal                                 :sc (sc-or-lose 'double-reg)                                 :offset (tn-offset reg)))           (reg2 (make-random-tn :kind :normal                                 :sc (sc-or-lose 'double-reg)                                 :offset (+ 2 (tn-offset reg)))))       (cond ((integerp offset)              (inst stdf reg0 base offset)              (inst stdf reg2 base (+ offset (* 2 n-word-bytes))))             (t              (inst stdf reg0 base offset)              (inst add offset (* 2 n-word-bytes))              (inst stdf reg2 base offset)              (when restore-offset                (inst sub offset (* 2 n-word-bytes)))))))))#!+long-float(define-move-fun (store-long 2) (vop x y)  ((long-reg) (long-stack))  (let ((nfp (current-nfp-tn vop))        (offset (* (tn-offset y) n-word-bytes)))    (store-long-reg x nfp offset)));;;; Move VOPs:;;; Exploit the V9 double-float move instruction. This is conditional;;; on the :sparc-v9 feature.(defun move-double-reg (dst src)  (cond    ((member :sparc-v9 *backend-subfeatures*)     (inst fmovd dst src))    (t     (dotimes (i 2)       (let ((dst (make-random-tn :kind :normal                                  :sc (sc-or-lose 'single-reg)                                  :offset (+ i (tn-offset dst))))             (src (make-random-tn :kind :normal                                  :sc (sc-or-lose 'single-reg)                                  :offset (+ i (tn-offset src)))))         (inst fmovs dst src))))));;; Exploit the V9 long-float move instruction. This is conditional;;; on the :sparc-v9 feature.(defun move-long-reg (dst src)  (cond    ((member :sparc-v9 *backend-subfeatures*)     (inst fmovq dst src))    (t     (dotimes (i 4)       (let ((dst (make-random-tn :kind :normal                                  :sc (sc-or-lose 'single-reg)                                  :offset (+ i (tn-offset dst))))             (src (make-random-tn :kind :normal                                  :sc (sc-or-lose 'single-reg)                                  :offset (+ i (tn-offset src)))))         (inst fmovs dst src))))))(macrolet ((frob (vop sc format)             `(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)                      ,@(ecase format                          (:single `((inst fmovs y x)))                          (:double `((move-double-reg y x)))                          (:long `((move-long-reg y x)))))))                (define-move-vop ,vop :move (,sc) (,sc)))))  (frob single-move single-reg :single)  (frob double-move double-reg :double)  #!+long-float  (frob long-move long-reg :long))(define-vop (move-from-float)  (:args (x :to :save))  (:results (y))  (:note "float to pointer coercion")  (:temporary (:scs (non-descriptor-reg)) ndescr)  (:variant-vars format size type data)  (:generator 13    (with-fixed-allocation (y ndescr type size)      (ecase format        (:single         (inst stf x y (- (* data n-word-bytes) other-pointer-lowtag)))        (:double         (inst stdf x y (- (* data n-word-bytes) other-pointer-lowtag)))        (:long         (store-long-reg x y (- (* data n-word-bytes)                                other-pointer-lowtag)))))))(macrolet ((frob (name sc &rest args)             `(progn                (define-vop (,name move-from-float)                  (:args (x :scs (,sc) :to :save))                  (:results (y :scs (descriptor-reg)))                  (:variant ,@args))                (define-move-vop ,name :move (,sc) (descriptor-reg)))))  (frob move-from-single single-reg :single    single-float-size single-float-widetag single-float-value-slot)  (frob move-from-double double-reg :double    double-float-size double-float-widetag double-float-value-slot)  #!+long-float  (frob move-from-long long-reg :long     long-float-size long-float-widetag long-float-value-slot))(macrolet ((frob (name sc format value)             `(progn                (define-vop (,name)                  (:args (x :scs (descriptor-reg)))                  (:results (y :scs (,sc)))                  (:note "pointer to float coercion")                  (:generator 2                    (inst ,(ecase format                             (:single 'ldf)                             (:double 'lddf))                          y x                          (- (* ,value n-word-bytes) other-pointer-lowtag))))                (define-move-vop ,name :move (descriptor-reg) (,sc)))))  (frob move-to-single single-reg :single single-float-value-slot)  (frob move-to-double double-reg :double double-float-value-slot))#!+long-float(define-vop (move-to-long)  (:args (x :scs (descriptor-reg)))  (:results (y :scs (long-reg)))  (:note "pointer to float coercion")  (:generator 2    (load-long-reg y x (- (* long-float-value-slot n-word-bytes)                          other-pointer-lowtag))))#!+long-float(define-move-vop move-to-long :move (descriptor-reg) (long-reg))(macrolet ((frob (name sc stack-sc format)             `(progn                (define-vop (,name)                  (:args (x :scs (,sc) :target y)                         (nfp :scs (any-reg)                              :load-if (not (sc-is y ,sc))))                  (:results (y))                  (:note "float argument move")                  (:generator ,(ecase format (:single 1) (:double 2))                    (sc-case y                      (,sc                       (unless (location= x y)                         ,@(ecase format                             (:single '((inst fmovs y x)))                             (:double '((move-double-reg y x))))))                      (,stack-sc                       (let ((offset (* (tn-offset y) n-word-bytes)))                         (inst ,(ecase format                                  (:single 'stf)                                  (:double 'stdf))                               x nfp offset))))))                (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))#!+long-float(define-vop (move-long-float-arg)  (:args (x :scs (long-reg) :target y)         (nfp :scs (any-reg) :load-if (not (sc-is y long-reg))))  (:results (y))  (:note "float argument move")  (:generator 3    (sc-case y      (long-reg       (unless (location= x y)         (move-long-reg y x)))      (long-stack       (let ((offset (* (tn-offset y) n-word-bytes)))         (store-long-reg x nfp offset))))));;;#!+long-float(define-move-vop move-long-float-arg :move-arg  (long-reg descriptor-reg) (long-reg));;;; 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 (+ (tn-offset x) 2)))#!+long-float(defun complex-long-reg-real-tn (x)  (make-random-tn :kind :normal :sc (sc-or-lose 'long-reg)                  :offset (tn-offset x)))#!+long-float(defun complex-long-reg-imag-tn (x)  (make-random-tn :kind :normal :sc (sc-or-lose 'long-reg)                  :offset (+ (tn-offset x) 4)))(define-move-fun (load-complex-single 2) (vop x y)  ((complex-single-stack) (complex-single-reg))  (let ((nfp (current-nfp-tn vop))        (offset (* (tn-offset x) n-word-bytes)))    (let ((real-tn (complex-single-reg-real-tn y)))      (inst ldf real-tn nfp offset))    (let ((imag-tn (complex-single-reg-imag-tn y)))      (inst ldf imag-tn nfp (+ offset n-word-bytes)))))(define-move-fun (store-complex-single 2) (vop x y)  ((complex-single-reg) (complex-single-stack))  (let ((nfp (current-nfp-tn vop))        (offset (* (tn-offset y) n-word-bytes)))    (let ((real-tn (complex-single-reg-real-tn x)))      (inst stf real-tn nfp offset))    (let ((imag-tn (complex-single-reg-imag-tn x)))      (inst stf imag-tn nfp (+ offset n-word-bytes)))))(define-move-fun (load-complex-double 4) (vop x y)  ((complex-double-stack) (complex-double-reg))  (let ((nfp (current-nfp-tn vop))        (offset (* (tn-offset x) n-word-bytes)))    (let ((real-tn (complex-double-reg-real-tn y)))      (inst lddf real-tn nfp offset))    (let ((imag-tn (complex-double-reg-imag-tn y)))      (inst lddf imag-tn nfp (+ offset (* 2 n-word-bytes))))))(define-move-fun (store-complex-double 4) (vop x y)  ((complex-double-reg) (complex-double-stack))  (let ((nfp (current-nfp-tn vop))        (offset (* (tn-offset y) n-word-bytes)))    (let ((real-tn (complex-double-reg-real-tn x)))      (inst stdf real-tn nfp offset))    (let ((imag-tn (complex-double-reg-imag-tn x)))      (inst stdf imag-tn nfp (+ offset (* 2 n-word-bytes))))))#!+long-float(define-move-fun (load-complex-long 5) (vop x y)  ((complex-long-stack) (complex-long-reg))  (let ((nfp (current-nfp-tn vop))        (offset (* (tn-offset x) n-word-bytes)))    (let ((real-tn (complex-long-reg-real-tn y)))      (load-long-reg real-tn nfp offset))    (let ((imag-tn (complex-long-reg-imag-tn y)))      (load-long-reg imag-tn nfp (+ offset (* 4 n-word-bytes))))))#!+long-float(define-move-fun (store-complex-long 5) (vop x y)  ((complex-long-reg) (complex-long-stack))  (let ((nfp (current-nfp-tn vop))        (offset (* (tn-offset y) n-word-bytes)))    (let ((real-tn (complex-long-reg-real-tn x)))      (store-long-reg real-tn nfp offset))    (let ((imag-tn (complex-long-reg-imag-tn x)))      (store-long-reg imag-tn nfp (+ offset (* 4 n-word-bytes))))));;;;;; Complex float register to register moves.;;;(define-vop (complex-single-move)  (:args (x :scs (complex-single-reg) :target y            :load-if (not (location= x y))))

⌨️ 快捷键说明

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