📄 float.lisp
字号:
(:args (x :scs (,from-sc) :target y)) (:results (y :scs (,to-sc))) (:arg-types ,from-type) (:result-types ,to-type) (:policy :fast-safe) (:note "inline float coercion") (:translate ,translate) (:vop-var vop) (:save-p :compute-only) (:generator 2 (note-this-location vop :internal-error) (inst ,inst y x))))) (frob %single-float/double-float %single-float cvtsd2ss double-reg double-float single-reg single-float) (frob %double-float/single-float %double-float cvtss2sd single-reg single-float double-reg double-float))(macrolet ((frob (trans inst from-sc from-type round-p) (declare (ignore round-p)) `(define-vop (,(symbolicate trans "/" from-type)) (:args (x :scs (,from-sc))) (:temporary (:sc any-reg) temp-reg) (:results (y :scs (signed-reg))) (:arg-types ,from-type) (:result-types signed-num) (:translate ,trans) (:policy :fast-safe) (:note "inline float truncate") (:vop-var vop) (:save-p :compute-only) (:generator 5 (sc-case y (signed-stack (inst ,inst temp-reg x) (move y temp-reg)) (signed-reg (inst ,inst y x) )))))) (frob %unary-truncate cvttss2si single-reg single-float nil) (frob %unary-truncate cvttsd2si double-reg double-float nil) (frob %unary-round cvtss2si single-reg single-float t) (frob %unary-round cvtsd2si double-reg double-float t))(define-vop (make-single-float) (:args (bits :scs (signed-reg) :target res :load-if (not (or (and (sc-is bits signed-stack) (sc-is res single-reg)) (and (sc-is bits signed-stack) (sc-is res single-stack) (location= bits res)))))) (:results (res :scs (single-reg single-stack))) (:arg-types signed-num) (:result-types single-float) (:translate make-single-float) (:policy :fast-safe) (:vop-var vop) (:generator 4 (sc-case res (single-stack (sc-case bits (signed-reg (inst mov res bits)) (signed-stack (aver (location= bits res))))) (single-reg (sc-case bits (signed-reg (inst movd res bits)) (signed-stack (inst movd res bits)))))))(define-vop (make-double-float) (:args (hi-bits :scs (signed-reg)) (lo-bits :scs (unsigned-reg))) (:results (res :scs (double-reg))) (:temporary (:sc unsigned-reg) temp) (:arg-types signed-num unsigned-num) (:result-types double-float) (:translate make-double-float) (:policy :fast-safe) (:vop-var vop) (:generator 2 (move temp hi-bits) (inst shl temp 32) (inst or temp lo-bits) (inst movd res temp)))(define-vop (single-float-bits) (:args (float :scs (single-reg descriptor-reg) :load-if (not (sc-is float single-stack)))) (:results (bits :scs (signed-reg))) (:temporary (:sc signed-stack :from :argument :to :result) stack-temp) (:arg-types single-float) (:result-types signed-num) (:translate single-float-bits) (:policy :fast-safe) (:vop-var vop) (:generator 4 (sc-case bits (signed-reg (sc-case float (single-reg (inst movss stack-temp float) (move bits stack-temp)) (single-stack (move bits float)) (descriptor-reg (move bits float) (inst shr bits 32)))) (signed-stack (sc-case float (single-reg (inst movss bits float))))) ;; Sign-extend (inst shl bits 32) (inst sar bits 32)))(define-vop (double-float-high-bits) (:args (float :scs (double-reg descriptor-reg) :load-if (not (sc-is float double-stack)))) (:results (hi-bits :scs (signed-reg))) (:temporary (:sc signed-stack :from :argument :to :result) temp) (:arg-types double-float) (:result-types signed-num) (:translate double-float-high-bits) (:policy :fast-safe) (:vop-var vop) (:generator 5 (sc-case float (double-reg (inst movsd temp float) (move hi-bits temp)) (double-stack (loadw hi-bits ebp-tn (- (1+ (tn-offset float))))) (descriptor-reg (loadw hi-bits float double-float-value-slot other-pointer-lowtag))) (inst sar hi-bits 32)))(define-vop (double-float-low-bits) (:args (float :scs (double-reg descriptor-reg) :load-if (not (sc-is float double-stack)))) (:results (lo-bits :scs (unsigned-reg))) (:temporary (:sc signed-stack :from :argument :to :result) temp) (:arg-types double-float) (:result-types unsigned-num) (:translate double-float-low-bits) (:policy :fast-safe) (:vop-var vop) (:generator 5 (sc-case float (double-reg (inst movsd temp float) (move lo-bits temp)) (double-stack (loadw lo-bits ebp-tn (- (1+ (tn-offset float))))) (descriptor-reg (loadw lo-bits float double-float-value-slot other-pointer-lowtag))) (inst shl lo-bits 32) (inst shr lo-bits 32)));;;; complex float VOPs(define-vop (make-complex-single-float) (:translate complex) (:args (real :scs (single-reg) :to :result :target r :load-if (not (location= real r))) (imag :scs (single-reg) :to :save)) (:arg-types single-float single-float) (:results (r :scs (complex-single-reg) :from (:argument 0) :load-if (not (sc-is r complex-single-stack)))) (:result-types complex-single-float) (:note "inline complex single-float creation") (:policy :fast-safe) (:generator 5 (sc-case r (complex-single-reg (let ((r-real (complex-single-reg-real-tn r))) (unless (location= real r-real) (inst movss r-real real))) (let ((r-imag (complex-single-reg-imag-tn r))) (unless (location= imag r-imag) (inst movss r-imag imag)))) (complex-single-stack (unless (location= real r) (inst movss (ea-for-csf-real-stack r) real)) (inst movss (ea-for-csf-imag-stack r) imag)))))(define-vop (make-complex-double-float) (:translate complex) (:args (real :scs (double-reg) :target r :load-if (not (location= real r))) (imag :scs (double-reg) :to :save)) (:arg-types double-float double-float) (:results (r :scs (complex-double-reg) :from (:argument 0) :load-if (not (sc-is r complex-double-stack)))) (:result-types complex-double-float) (:note "inline complex double-float creation") (:policy :fast-safe) (:generator 5 (sc-case r (complex-double-reg (let ((r-real (complex-double-reg-real-tn r))) (unless (location= real r-real) (inst movsd r-real real))) (let ((r-imag (complex-double-reg-imag-tn r))) (unless (location= imag r-imag) (inst movsd r-imag imag)))) (complex-double-stack (unless (location= real r) (inst movsd (ea-for-cdf-real-stack r) real)) (inst movsd (ea-for-cdf-imag-stack r) imag)))))(define-vop (complex-float-value) (:args (x :target r)) (:results (r)) (:variant-vars offset) (:policy :fast-safe) (:generator 3 (cond ((sc-is x complex-single-reg complex-double-reg) (let ((value-tn (make-random-tn :kind :normal :sc (sc-or-lose 'double-reg) :offset (+ offset (tn-offset x))))) (unless (location= value-tn r) (if (sc-is x complex-single-reg) (inst movss r value-tn) (inst movsd r value-tn))))) ((sc-is r single-reg) (let ((ea (sc-case x (complex-single-stack (ecase offset (0 (ea-for-csf-real-stack x)) (1 (ea-for-csf-imag-stack x)))) (descriptor-reg (ecase offset (0 (ea-for-csf-real-desc x)) (1 (ea-for-csf-imag-desc x))))))) (inst movss r ea))) ((sc-is r double-reg) (let ((ea (sc-case x (complex-double-stack (ecase offset (0 (ea-for-cdf-real-stack x)) (1 (ea-for-cdf-imag-stack x)))) (descriptor-reg (ecase offset (0 (ea-for-cdf-real-desc x)) (1 (ea-for-cdf-imag-desc x))))))) (inst movsd r ea))) (t (error "COMPLEX-FLOAT-VALUE VOP failure")))))(define-vop (realpart/complex-single-float complex-float-value) (:translate realpart) (:args (x :scs (complex-single-reg complex-single-stack descriptor-reg) :target r)) (:arg-types complex-single-float) (:results (r :scs (single-reg))) (:result-types single-float) (:note "complex float realpart") (:variant 0))(define-vop (realpart/complex-double-float complex-float-value) (:translate realpart) (:args (x :scs (complex-double-reg complex-double-stack descriptor-reg) :target r)) (:arg-types complex-double-float) (:results (r :scs (double-reg))) (:result-types double-float) (:note "complex float realpart") (:variant 0))(define-vop (imagpart/complex-single-float complex-float-value) (:translate imagpart) (:args (x :scs (complex-single-reg complex-single-stack descriptor-reg) :target r)) (:arg-types complex-single-float) (:results (r :scs (single-reg))) (:result-types single-float) (:note "complex float imagpart") (:variant 1))(define-vop (imagpart/complex-double-float complex-float-value) (:translate imagpart) (:args (x :scs (complex-double-reg complex-double-stack descriptor-reg) :target r)) (:arg-types complex-double-float) (:results (r :scs (double-reg))) (:result-types double-float) (:note "complex float imagpart") (:variant 1));;; hack dummy VOPs to bias the representation selection of their;;; arguments towards a FP register, which can help avoid consing at;;; inappropriate locations(defknown double-float-reg-bias (double-float) (values))(define-vop (double-float-reg-bias) (:translate double-float-reg-bias) (:args (x :scs (double-reg double-stack) :load-if nil)) (:arg-types double-float) (:policy :fast-safe) (:note "inline dummy FP register bias") (:ignore x) (:generator 0))(defknown single-float-reg-bias (single-float) (values))(define-vop (single-float-reg-bias) (:translate single-float-reg-bias) (:args (x :scs (single-reg single-stack) :load-if nil)) (:arg-types single-float) (:policy :fast-safe) (:note "inline dummy FP register bias") (:ignore x) (:generator 0))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -