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

📄 float.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 3 页
字号:
;;;; the MIPS VM definition of floating point operations;;;; 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");;;; Move functions:(define-move-fun (load-single 1) (vop x y)  ((single-stack) (single-reg))  (inst lwc1 y (current-nfp-tn vop) (* (tn-offset x) n-word-bytes))  (inst nop))(define-move-fun (store-single 1) (vop x y)  ((single-reg) (single-stack))  (inst swc1 x (current-nfp-tn vop) (* (tn-offset y) n-word-bytes)))(defun ld-double (r base offset)  (ecase *backend-byte-order*    (:big-endian     (inst lwc1 r base (+ offset n-word-bytes))     (inst lwc1-odd r base offset))    (:little-endian     (inst lwc1 r base offset)     (inst lwc1-odd r base (+ offset 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)))    (ld-double y nfp offset))  (inst nop))(defun str-double (x base offset)  (ecase *backend-byte-order*    (:big-endian     (inst swc1 x base (+ offset n-word-bytes))     (inst swc1-odd x base offset))    (:little-endian     (inst swc1 x base offset)     (inst swc1-odd x base (+ offset n-word-bytes)))))(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)))    (str-double x nfp offset)));;;; Move VOPs:(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)                      (inst fmove ,format y x))))                (define-move-vop ,vop :move (,sc) (,sc)))))  (frob single-move single-reg :single)  (frob double-move double-reg :double))(define-vop (move-from-float)  (:args (x :to :save))  (:results (y))  (:temporary (:scs (non-descriptor-reg)) ndescr)  (:temporary (:sc non-descriptor-reg :offset nl4-offset) pa-flag)  (:variant-vars double-p size type data)  (:note "float to pointer coercion")  (:generator 13    (with-fixed-allocation (y pa-flag ndescr type size nil)      (if double-p          (str-double x y (- (* data n-word-bytes) other-pointer-lowtag))          (inst swc1 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    nil single-float-size single-float-widetag single-float-value-slot)  (frob move-from-double double-reg    t double-float-size double-float-widetag double-float-value-slot))(macrolet ((frob (name sc double-p value)             `(progn                (define-vop (,name)                  (:args (x :scs (descriptor-reg)))                  (:results (y :scs (,sc)))                  (:note "pointer to float coercion")                  (:generator 2                    ,@(ecase *backend-byte-order*                        (:big-endian                         (cond                          (double-p                           `((inst lwc1 y x (- (* (1+ ,value) n-word-bytes)                                               other-pointer-lowtag))                             (inst lwc1-odd y x (- (* ,value n-word-bytes)                                                   other-pointer-lowtag))))                          (t                           `((inst lwc1 y x (- (* ,value n-word-bytes)                                               other-pointer-lowtag))))))                        (:little-endian                         `((inst lwc1 y x (- (* ,value n-word-bytes)                                             other-pointer-lowtag))                           ,@(when double-p                               `((inst lwc1-odd y x                                       (- (* (1+ ,value) n-word-bytes)                                          other-pointer-lowtag)))))))                    (inst nop)))                (define-move-vop ,name :move (descriptor-reg) (,sc)))))  (frob move-to-single single-reg nil single-float-value-slot)  (frob move-to-double double-reg t double-float-value-slot))(macrolet ((frob (name sc stack-sc format double-p)             `(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 ,(if double-p 2 1)                    (sc-case y                      (,sc                       (unless (location= x y)                         (inst fmove ,format y x)))                      (,stack-sc                       (let ((offset (* (tn-offset y) n-word-bytes)))                         ,@(ecase *backend-byte-order*                             (:big-endian                              (cond                               (double-p                                '((inst swc1 x nfp (+ offset n-word-bytes))                                  (inst swc1-odd x nfp offset)))                               (t                                '((inst swc1 x nfp offset)))))                             (:little-endian                              `((inst swc1 x nfp offset)                                ,@(when double-p                                    '((inst swc1-odd x nfp                                            (+ offset n-word-bytes))))))))))))                (define-move-vop ,name :move-arg                  (,sc descriptor-reg) (,sc)))))  (frob move-single-float-arg single-reg single-stack :single nil)  (frob move-double-float-arg double-reg double-stack :double t));;;; 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 (+ (tn-offset x) 2)))(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)))(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 lwc1 real-tn nfp offset))    (let ((imag-tn (complex-single-reg-imag-tn y)))      (inst lwc1 imag-tn nfp (+ offset n-word-bytes))))  (inst nop))(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 swc1 real-tn nfp offset))    (let ((imag-tn (complex-single-reg-imag-tn x)))      (inst swc1 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)))      (ld-double real-tn nfp offset))    (let ((imag-tn (complex-double-reg-imag-tn y)))      (ld-double imag-tn nfp (+ offset (* 2 n-word-bytes))))    (inst nop)))(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)))      (str-double real-tn nfp offset))    (let ((imag-tn (complex-double-reg-imag-tn x)))      (str-double imag-tn nfp (+ offset (* 2 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))))  (:results (y :scs (complex-single-reg) :load-if (not (location= x y))))  (:note "complex single 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.       (let ((x-real (complex-single-reg-real-tn x))             (y-real (complex-single-reg-real-tn y)))         (inst fmove :single y-real x-real))       (let ((x-imag (complex-single-reg-imag-tn x))             (y-imag (complex-single-reg-imag-tn y)))         (inst fmove :single y-imag x-imag)))))(define-move-vop complex-single-move :move  (complex-single-reg) (complex-single-reg))(define-vop (complex-double-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))))  (:note "complex double 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.       (let ((x-real (complex-double-reg-real-tn x))             (y-real (complex-double-reg-real-tn y)))         (inst fmove :double y-real x-real))       (let ((x-imag (complex-double-reg-imag-tn x))             (y-imag (complex-double-reg-imag-tn y)))         (inst fmove :double y-imag x-imag)))))(define-move-vop complex-double-move :move  (complex-double-reg) (complex-double-reg));;; Move from a complex float to a descriptor register 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)))  (:temporary (:scs (non-descriptor-reg)) ndescr)  (:temporary (:sc non-descriptor-reg :offset nl4-offset) pa-flag)  (:note "complex single float to pointer coercion")  (:generator 13    (with-fixed-allocation (y pa-flag ndescr complex-single-float-widetag                              complex-single-float-size nil)      (let ((real-tn (complex-single-reg-real-tn x)))        (inst swc1 real-tn y (- (* complex-single-float-real-slot                                   n-word-bytes)                                other-pointer-lowtag)))      (let ((imag-tn (complex-single-reg-imag-tn x)))        (inst swc1 imag-tn y (- (* complex-single-float-imag-slot                                   n-word-bytes)                                other-pointer-lowtag))))))(define-move-vop move-from-complex-single :move  (complex-single-reg) (descriptor-reg))

⌨️ 快捷键说明

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