(defun ld-float (offset base r)
(cond ((< offset (ash 1 4))
- (inst flds offset base r))
- (t
- (inst ldo offset zero-tn lip-tn)
- (inst fldx lip-tn base r))))
+ (inst flds offset base r))
+ ((and (< offset (ash 1 13))
+ (> offset 0))
+ (inst ldo offset zero-tn lip-tn)
+ (inst fldx lip-tn base r))
+ (t
+ (error "ld-float: bad offset: ~s~%" offset))))
(define-move-fun (load-float 1) (vop x y)
((single-stack) (single-reg)
(defun str-float (x offset base)
(cond ((< offset (ash 1 4))
- (inst fsts x offset base))
- (t
- (inst ldo offset zero-tn lip-tn)
- (inst fstx x lip-tn base))))
+ ;(note-next-instruction vop :internal-error)
+ (inst fsts x offset base))
+ ((and (< offset (ash 1 13))
+ (> offset 0))
+ ;; FIXME-lav, ok with GC to use lip-tn for arbitrary offsets ?
+ (inst ldo offset zero-tn lip-tn)
+ ;(note-next-instruction vop :internal-error)
+ (inst fstx x lip-tn base))
+ (t
+ (error "str-float: bad offset: ~s~%" offset))))
(define-move-fun (store-float 1) (vop x y)
((single-reg) (single-stack)
;;;; Move VOPs
(define-vop (move-float)
(:args (x :scs (single-reg double-reg)
- :target y
- :load-if (not (location= x y))))
+ :target y
+ :load-if (not (location= x y))))
(:results (y :scs (single-reg double-reg)
- :load-if (not (location= x y))))
+ :load-if (not (location= x y))))
(:note "float move")
(:generator 0
(unless (location= y x)
(:variant-vars size type data)
(:note "float to pointer coercion")
(:generator 13
- (with-fixed-allocation (y ndescr type size))
- (inst fsts x (- (* data n-word-bytes) other-pointer-lowtag) y)))
+ (with-fixed-allocation (y nil ndescr type size nil)
+ (inst fsts x (- (* data n-word-bytes) other-pointer-lowtag) y))))
(macrolet ((frob (name sc &rest args)
- `(progn
- (define-vop (,name move-from-float)
- (:args (x :scs (,sc) :to :save))
- (:variant ,@args))
- (define-move-vop ,name :move (,sc) (descriptor-reg)))))
+ `(progn
+ (define-vop (,name move-from-float)
+ (:args (x :scs (,sc) :to :save))
+ (:variant ,@args))
+ (define-move-vop ,name :move (,sc) (descriptor-reg)))))
(frob move-from-single single-reg
single-float-size single-float-widetag single-float-value-slot)
(frob move-from-double double-reg
(inst flds (- (* offset n-word-bytes) other-pointer-lowtag) x y)))
(macrolet ((frob (name sc offset)
- `(progn
- (define-vop (,name move-to-float)
- (:results (y :scs (,sc)))
- (:variant ,offset))
- (define-move-vop ,name :move (descriptor-reg) (,sc)))))
+ `(progn
+ (define-vop (,name move-to-float)
+ (:results (y :scs (,sc)))
+ (:variant ,offset))
+ (define-move-vop ,name :move (descriptor-reg) (,sc)))))
(frob move-to-single single-reg single-float-value-slot)
(frob move-to-double double-reg double-float-value-slot))
(define-vop (move-float-arg)
(:args (x :scs (single-reg double-reg) :target y)
- (nfp :scs (any-reg)
- :load-if (not (sc-is y single-reg double-reg))))
+ (nfp :scs (any-reg)
+ :load-if (not (sc-is y single-reg double-reg))))
(:results (y))
(:note "float argument move")
(:generator 1
(sc-case y
((single-reg double-reg)
(unless (location= x y)
- (inst funop :copy x y)))
+ (inst funop :copy x y)))
((single-stack double-stack)
(let ((offset (* (tn-offset y) n-word-bytes)))
- (str-float x offset nfp))))))
+ (str-float x offset nfp))))))
(define-move-vop move-float-arg :move-arg
(single-reg descriptor-reg) (single-reg))
(define-move-vop move-float-arg :move-arg
;;;; 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)))
+ :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))))
+ :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)))
+ (make-random-tn :kind :normal :sc (sc-or-lose 'complex-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))))
-
-(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)))
- (ld-float offset nfp real-tn))
- (let ((imag-tn (complex-single-reg-imag-tn y)))
- (ld-float (+ offset n-word-bytes) nfp imag-tn))))
-
-(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)))
- (str-float real-tn offset nfp))
- (let ((imag-tn (complex-single-reg-imag-tn x)))
- (str-float imag-tn (+ offset n-word-bytes) nfp))))
-
-(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-float offset nfp real-tn))
- (let ((imag-tn (complex-double-reg-imag-tn y)))
- (ld-float (+ offset (* 2 n-word-bytes)) nfp imag-tn))))
-
-(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-float real-tn offset nfp))
- (let ((imag-tn (complex-double-reg-imag-tn x)))
- (str-float imag-tn (+ offset (* 2 n-word-bytes)) nfp))))
+ (make-random-tn :kind :normal :sc (sc-or-lose 'complex-double-reg)
+ :offset (1+ (tn-offset x))))
+
+(macrolet
+ ((def-move-fun (dir type size from to)
+ `(define-move-fun (,(symbolicate dir "-" type) ,size) (vop x y)
+ ((,(symbolicate type "-" from)) (,(symbolicate type "-" to)))
+ (let ((nfp (current-nfp-tn vop))
+ (offset (* (tn-offset ,(if (eq dir 'load) 'x 'y)) n-word-bytes)))
+ ,@(if (eq dir 'load)
+ `((let ((real-tn (,(symbolicate type "-REG-REAL-TN") y)))
+ (ld-float offset nfp real-tn))
+ (let ((imag-tn (,(symbolicate type "-REG-IMAG-TN") y)))
+ (ld-float (+ offset n-word-bytes) nfp imag-tn)))
+ `((let ((real-tn (,(symbolicate type "-REG-REAL-TN") x)))
+ (str-float real-tn offset nfp))
+ (let ((imag-tn (,(symbolicate type "-REG-IMAG-TN") x)))
+ (str-float imag-tn
+ (+ offset (* ,(/ size 2) n-word-bytes))
+ nfp))))))))
+ (def-move-fun load complex-single 2 stack reg)
+ (def-move-fun store complex-single 2 reg stack)
+ (def-move-fun load complex-double 4 stack reg)
+ (def-move-fun store complex-double 4 reg stack))
;;; 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))))
+ :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
;; 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 funop :copy x-real y-real))
+ (y-real (complex-single-reg-real-tn y)))
+ (inst funop :copy x-real y-real))
(let ((x-imag (complex-single-reg-imag-tn x))
- (y-imag (complex-single-reg-imag-tn y)))
- (inst funop :copy x-imag y-imag)))))
+ (y-imag (complex-single-reg-imag-tn y)))
+ (inst funop :copy x-imag y-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))))
+ :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
;; 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 funop :copy x-real y-real))
+ (y-real (complex-double-reg-real-tn y)))
+ (inst funop :copy x-real y-real))
(let ((x-imag (complex-double-reg-imag-tn x))
- (y-imag (complex-double-reg-imag-tn y)))
- (inst funop :copy x-imag y-imag)))))
+ (y-imag (complex-double-reg-imag-tn y)))
+ (inst funop :copy x-imag y-imag)))))
(define-move-vop complex-double-move :move
(complex-double-reg) (complex-double-reg))
(:temporary (:scs (non-descriptor-reg)) ndescr)
(:note "complex single float to pointer coercion")
(:generator 13
- (with-fixed-allocation (y ndescr complex-single-float-widetag
- complex-single-float-size))
- (let ((real-tn (complex-single-reg-real-tn x)))
- (inst fsts real-tn (- (* complex-single-float-real-slot n-word-bytes)
- other-pointer-lowtag)
- y))
- (let ((imag-tn (complex-single-reg-imag-tn x)))
- (inst fsts imag-tn (- (* complex-single-float-imag-slot n-word-bytes)
- other-pointer-lowtag)
- y))))
+ (with-fixed-allocation (y nil ndescr complex-single-float-widetag
+ complex-single-float-size nil)
+ (let ((real-tn (complex-single-reg-real-tn x)))
+ (inst fsts real-tn (- (* complex-single-float-real-slot n-word-bytes)
+ other-pointer-lowtag) y))
+ (let ((imag-tn (complex-single-reg-imag-tn x)))
+ (inst fsts imag-tn (- (* complex-single-float-imag-slot n-word-bytes)
+ other-pointer-lowtag) y)))))
(define-move-vop move-from-complex-single :move
(complex-single-reg) (descriptor-reg))
(:temporary (:scs (non-descriptor-reg)) ndescr)
(:note "complex double float to pointer coercion")
(:generator 13
- (with-fixed-allocation (y ndescr complex-double-float-widetag
- complex-double-float-size))
- (let ((real-tn (complex-double-reg-real-tn x)))
- (inst fsts real-tn (- (* complex-double-float-real-slot n-word-bytes)
- other-pointer-lowtag)
- y))
- (let ((imag-tn (complex-double-reg-imag-tn x)))
- (inst fsts imag-tn (- (* complex-double-float-imag-slot n-word-bytes)
- other-pointer-lowtag)
- y))))
+ (with-fixed-allocation (y nil ndescr complex-double-float-widetag
+ complex-double-float-size nil)
+ (let ((real-tn (complex-double-reg-real-tn x)))
+ (inst fsts real-tn (- (* complex-double-float-real-slot n-word-bytes)
+ other-pointer-lowtag) y))
+ (let ((imag-tn (complex-double-reg-imag-tn x)))
+ (inst fsts imag-tn (- (* complex-double-float-imag-slot n-word-bytes)
+ other-pointer-lowtag) y)))))
(define-move-vop move-from-complex-double :move
(complex-double-reg) (descriptor-reg))
(:generator 2
(let ((real-tn (complex-single-reg-real-tn y)))
(inst flds (- (* complex-single-float-real-slot n-word-bytes)
- other-pointer-lowtag)
- x real-tn))
+ other-pointer-lowtag)
+ x real-tn))
(let ((imag-tn (complex-single-reg-imag-tn y)))
(inst flds (- (* complex-single-float-imag-slot n-word-bytes)
- other-pointer-lowtag)
- x imag-tn))))
+ other-pointer-lowtag)
+ x imag-tn))))
(define-move-vop move-to-complex-single :move
(descriptor-reg) (complex-single-reg))
(:generator 2
(let ((real-tn (complex-double-reg-real-tn y)))
(inst flds (- (* complex-double-float-real-slot n-word-bytes)
- other-pointer-lowtag)
- x real-tn))
+ other-pointer-lowtag)
+ x real-tn))
(let ((imag-tn (complex-double-reg-imag-tn y)))
(inst flds (- (* complex-double-float-imag-slot n-word-bytes)
- other-pointer-lowtag)
- x imag-tn))))
+ other-pointer-lowtag)
+ x imag-tn))))
(define-move-vop move-to-complex-double :move
(descriptor-reg) (complex-double-reg))
;;; Complex float move-arg vop
(define-vop (move-complex-single-float-arg)
(:args (x :scs (complex-single-reg) :target y)
- (nfp :scs (any-reg) :load-if (not (sc-is y complex-single-reg))))
+ (nfp :scs (any-reg) :load-if (not (sc-is y complex-single-reg))))
(:results (y))
(:note "float argument move")
(:generator 1
(sc-case y
(complex-single-reg
(unless (location= x y)
- (let ((x-real (complex-single-reg-real-tn x))
- (y-real (complex-single-reg-real-tn y)))
- (inst funop :copy x-real y-real))
- (let ((x-imag (complex-single-reg-imag-tn x))
- (y-imag (complex-single-reg-imag-tn y)))
- (inst funop :copy x-imag y-imag))))
+ (let ((x-real (complex-single-reg-real-tn x))
+ (y-real (complex-single-reg-real-tn y)))
+ (inst funop :copy x-real y-real))
+ (let ((x-imag (complex-single-reg-imag-tn x))
+ (y-imag (complex-single-reg-imag-tn y)))
+ (inst funop :copy x-imag y-imag))))
(complex-single-stack
(let ((offset (* (tn-offset y) n-word-bytes)))
- (let ((real-tn (complex-single-reg-real-tn x)))
- (str-float real-tn offset nfp))
- (let ((imag-tn (complex-single-reg-imag-tn x)))
- (str-float imag-tn (+ offset n-word-bytes) nfp)))))))
+ (let ((real-tn (complex-single-reg-real-tn x)))
+ (str-float real-tn offset nfp))
+ (let ((imag-tn (complex-single-reg-imag-tn x)))
+ (str-float imag-tn (+ offset n-word-bytes) nfp)))))))
(define-move-vop move-complex-single-float-arg :move-arg
(complex-single-reg descriptor-reg) (complex-single-reg))
(define-vop (move-complex-double-float-arg)
(:args (x :scs (complex-double-reg) :target y)
- (nfp :scs (any-reg) :load-if (not (sc-is y complex-double-reg))))
+ (nfp :scs (any-reg) :load-if (not (sc-is y complex-double-reg))))
(:results (y))
(:note "float argument move")
(:generator 1
(sc-case y
(complex-double-reg
(unless (location= x y)
- (let ((x-real (complex-double-reg-real-tn x))
- (y-real (complex-double-reg-real-tn y)))
- (inst funop :copy x-real y-real))
- (let ((x-imag (complex-double-reg-imag-tn x))
- (y-imag (complex-double-reg-imag-tn y)))
- (inst funop :copy x-imag y-imag))))
+ (let ((x-real (complex-double-reg-real-tn x))
+ (y-real (complex-double-reg-real-tn y)))
+ (inst funop :copy x-real y-real))
+ (let ((x-imag (complex-double-reg-imag-tn x))
+ (y-imag (complex-double-reg-imag-tn y)))
+ (inst funop :copy x-imag y-imag))))
(complex-double-stack
(let ((offset (* (tn-offset y) n-word-bytes)))
- (let ((real-tn (complex-double-reg-real-tn x)))
- (str-float real-tn offset nfp))
- (let ((imag-tn (complex-double-reg-imag-tn x)))
- (str-float imag-tn (+ offset (* 2 n-word-bytes)) nfp)))))))
+ (let ((real-tn (complex-double-reg-real-tn x)))
+ (str-float real-tn offset nfp))
+ (let ((imag-tn (complex-double-reg-imag-tn x)))
+ (str-float imag-tn (+ offset (* 2 n-word-bytes)) nfp)))))))
(define-move-vop move-complex-double-float-arg :move-arg
(complex-double-reg descriptor-reg) (complex-double-reg))
(single-reg double-reg complex-single-reg complex-double-reg)
(descriptor-reg))
\f
+;;;; stuff for c-call float-in-int-register arguments
+(define-vop (move-to-single-int-reg)
+ (:note "pointer to float-in-int coercion")
+ (:args (x :scs (single-reg descriptor-reg)))
+ (:results (y :scs (single-int-carg-reg) :load-if nil))
+ (:generator 1
+ (sc-case x
+ (single-reg
+ (inst funop :copy x y))
+ (descriptor-reg
+ (inst ldw (- (* single-float-value-slot n-word-bytes)
+ other-pointer-lowtag) x y)))))
+(define-move-vop move-to-single-int-reg
+ :move (single-reg descriptor-reg) (single-int-carg-reg))
+
+(define-vop (move-single-int-reg)
+ (:args (x :target y :scs (single-int-carg-reg) :load-if nil)
+ (fp :scs (any-reg) :load-if (not (sc-is y single-int-carg-reg))))
+ (:results (y :scs (single-int-carg-reg) :load-if nil))
+ (:generator 1
+ (unless (location= x y)
+ (error "Huh? why did it do that?"))))
+(define-move-vop move-single-int-reg :move-arg
+ (single-int-carg-reg) (single-int-carg-reg))
+
+; move contents of float register x to register y
+(define-vop (move-to-double-int-reg)
+ (:note "pointer to float-in-int coercion")
+ (:args (x :scs (double-reg descriptor-reg)))
+ (:results (y :scs (double-int-carg-reg) :load-if nil))
+ (:temporary (:scs (signed-stack) :to (:result 0)) temp)
+ (:temporary (:scs (signed-reg) :to (:result 0) :target y) old1)
+ (:temporary (:scs (signed-reg) :to (:result 0) :target y) old2)
+ (:vop-var vop)
+ (:save-p :compute-only)
+ (:generator 2
+ (sc-case x
+ (double-reg
+ (let* ((nfp (current-nfp-tn vop))
+ (stack-tn (sc-case y
+ (double-stack y)
+ (double-int-carg-reg temp)))
+ (offset (* (tn-offset stack-tn) n-word-bytes)))
+ ;; save 8 bytes of stack to two register,
+ ;; write down float in stack and load it back
+ ;; into result register. Notice the result hack,
+ ;; we are writing to one extra register.
+ ;; Double float argument convention uses two registers,
+ ;; but we only know about one (thanks to c-call).
+ (inst ldw offset nfp old1)
+ (inst ldw (+ offset n-word-bytes) nfp old2)
+ (str-float x offset nfp) ; writes 8 bytes
+ (inst ldw offset nfp y)
+ (inst ldw (+ offset n-word-bytes) nfp
+ (make-wired-tn (primitive-type-or-lose 'unsigned-byte-32)
+ (sc-number-or-lose 'unsigned-reg)
+ (+ 1 (tn-offset y))))
+ (inst stw old1 offset nfp)
+ (inst stw old2 (+ offset n-word-bytes) nfp)))
+ (descriptor-reg
+ (inst ldw (- (* double-float-value-slot n-word-bytes)
+ other-pointer-lowtag) x y)
+ (inst ldw (- (* (1+ double-float-value-slot) n-word-bytes)
+ other-pointer-lowtag) x
+ (make-wired-tn (primitive-type-or-lose 'unsigned-byte-32)
+ (sc-number-or-lose 'unsigned-reg)
+ (+ 1 (tn-offset y))))))))
+(define-move-vop move-to-double-int-reg
+ :move (double-reg descriptor-reg) (double-int-carg-reg))
+
+(define-vop (move-double-int-reg)
+ (:args (x :target y :scs (double-int-carg-reg) :load-if nil)
+ (fp :scs (any-reg) :load-if (not (sc-is y double-int-carg-reg))))
+ (:results (y :scs (double-int-carg-reg) :load-if nil))
+ (:generator 2
+ (unless (location= x y)
+ (error "Huh? why did it do that?"))))
+(define-move-vop move-double-int-reg :move-arg
+ (double-int-carg-reg) (double-int-carg-reg))
+
;;;; Arithmetic VOPs.
(define-vop (float-op)
(:note "inline float arithmetic")
(:vop-var vop)
(:save-p :compute-only)
- (:node-var node)
(:generator 0
- (inst fbinop operation x y r)
- (when (policy node (or (= debug 3) (> safety speed)))
- (note-next-instruction vop :internal-error)
- (inst fsts fp-single-zero-tn 0 csp-tn))))
+ (note-this-location vop :internal-error)
+ (inst fbinop operation x y r)))
(macrolet ((frob (name sc zero-sc ptype)
- `(define-vop (,name float-op)
- (:args (x :scs (,sc ,zero-sc))
- (y :scs (,sc ,zero-sc)))
- (:results (r :scs (,sc)))
- (:arg-types ,ptype ,ptype)
- (:result-types ,ptype))))
+ `(define-vop (,name float-op)
+ (:args (x :scs (,sc ,zero-sc))
+ (y :scs (,sc ,zero-sc)))
+ (:results (r :scs (,sc)))
+ (:arg-types ,ptype ,ptype)
+ (:result-types ,ptype))))
(frob single-float-op single-reg fp-single-zero single-float)
(frob double-float-op double-reg fp-double-zero double-float))
(macrolet ((frob (translate op sname scost dname dcost)
- `(progn
- (define-vop (,sname single-float-op)
- (:translate ,translate)
- (:variant ,op)
- (:variant-cost ,scost))
- (define-vop (,dname double-float-op)
- (:translate ,translate)
- (:variant ,op)
- (:variant-cost ,dcost)))))
+ `(progn
+ (define-vop (,sname single-float-op)
+ (:translate ,translate)
+ (:variant ,op)
+ (:variant-cost ,scost))
+ (define-vop (,dname double-float-op)
+ (:translate ,translate)
+ (:variant ,op)
+ (:variant-cost ,dcost)))))
(frob + :add +/single-float 2 +/double-float 2)
(frob - :sub -/single-float 2 -/double-float 2)
(frob * :mpy */single-float 4 */double-float 5)
(frob / :div //single-float 12 //double-float 19))
-
(macrolet ((frob (name translate sc type inst)
- `(define-vop (,name)
- (:args (x :scs (,sc)))
- (:results (y :scs (,sc)))
- (:translate ,translate)
- (:policy :fast-safe)
- (:arg-types ,type)
- (:result-types ,type)
- (:note "inline float arithmetic")
- (:vop-var vop)
- (:save-p :compute-only)
- (:node-var node)
- (:generator 1
- ,inst
- (when (policy node (or (= debug 3) (> safety speed)))
- (note-next-instruction vop :internal-error)
- (inst fsts fp-single-zero-tn 0 csp-tn))))))
+ `(define-vop (,name)
+ (:args (x :scs (,sc)))
+ (:results (y :scs (,sc)))
+ (:translate ,translate)
+ (:policy :fast-safe)
+ (:arg-types ,type)
+ (:result-types ,type)
+ (:note "inline float arithmetic")
+ (:vop-var vop)
+ (:save-p :compute-only)
+ (:generator 1
+ (note-this-location vop :internal-error)
+ ,inst))))
(frob abs/single-float abs single-reg single-float
(inst funop :abs x y))
(frob abs/double-float abs double-reg double-float
(:vop-var vop)
(:save-p :compute-only)
(:generator 3
+ (note-this-location vop :internal-error)
;; This is the condition to nullify the branch, so it is inverted.
(inst fcmp (if not-p condition complement) x y)
- (note-next-instruction vop :internal-error)
(inst ftest)
(inst b target :nullify t)))
(macrolet ((frob (name sc zero-sc ptype)
- `(define-vop (,name float-compare)
- (:args (x :scs (,sc ,zero-sc))
- (y :scs (,sc ,zero-sc)))
- (:arg-types ,ptype ,ptype))))
+ `(define-vop (,name float-compare)
+ (:args (x :scs (,sc ,zero-sc))
+ (y :scs (,sc ,zero-sc)))
+ (:arg-types ,ptype ,ptype))))
(frob single-float-compare single-reg fp-single-zero single-float)
(frob double-float-compare double-reg fp-double-zero double-float))
(macrolet ((frob (translate condition complement sname dname)
- `(progn
- (define-vop (,sname single-float-compare)
- (:translate ,translate)
- (:variant ,condition ,complement))
- (define-vop (,dname double-float-compare)
- (:translate ,translate)
- (:variant ,condition ,complement)))))
+ `(progn
+ (define-vop (,sname single-float-compare)
+ (:translate ,translate)
+ (:variant ,condition ,complement))
+ (define-vop (,dname double-float-compare)
+ (:translate ,translate)
+ (:variant ,condition ,complement)))))
+ ;; FIXME-lav: let 'inst cmp' translate keywords into raw binary instead of giving it here
(frob < #b01001 #b10101 </single-float </double-float)
(frob > #b10001 #b01101 >/single-float >/double-float)
(frob = #b00101 #b11001 eql/single-float eql/double-float))
;;;; Conversion:
(macrolet ((frob (name translate from-sc from-type to-sc to-type)
- `(define-vop (,name)
- (:args (x :scs (,from-sc)))
- (: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)
- (:node-var node)
- (:generator 2
- (inst fcnvff x y)
- (when (policy node (or (= debug 3) (> safety speed)))
- (note-next-instruction vop :internal-error)
- (inst fsts fp-single-zero-tn 0 csp-tn))))))
+ `(define-vop (,name)
+ (:args (x :scs (,from-sc)))
+ (: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 fcnvff x y)))))
(frob %single-float/double-float %single-float
double-reg double-float
single-reg single-float)
single-reg single-float
double-reg double-float))
+; convert register-integer to registersingle/double by
+; putting it on single-float-stack and then float-loading it into
+; an float register, and finally convert the float-register and
+; storing the result into y
(macrolet ((frob (name translate to-sc to-type)
- `(define-vop (,name)
- (:args (x :scs (signed-reg)
- :load-if (not (sc-is x signed-stack))
- :target stack-temp))
- (:arg-types signed-num)
- (:results (y :scs (,to-sc)))
- (:result-types ,to-type)
- (:policy :fast-safe)
- (:note "inline float coercion")
- (:translate ,translate)
- (:vop-var vop)
- (:save-p :compute-only)
- (:node-var node)
- (:temporary (:scs (signed-stack) :from (:argument 0))
- stack-temp)
- (:temporary (:scs (single-reg) :to (:result 0) :target y)
- fp-temp)
- (:temporary (:scs (any-reg) :from (:argument 0)
- :to (:result 0)) index)
- (:generator 5
- (let* ((nfp (current-nfp-tn vop))
- (stack-tn
- (sc-case x
- (signed-stack
- x)
- (signed-reg
- (storew x nfp (tn-offset stack-temp))
- stack-temp)))
- (offset (* (tn-offset stack-tn) n-word-bytes)))
- (cond ((< offset (ash 1 4))
- (inst flds offset nfp fp-temp))
- (t
- (inst ldo offset zero-tn index)
- (inst fldx index nfp fp-temp)))
- (inst fcnvxf fp-temp y)
- (when (policy node (or (= debug 3) (> safety speed)))
- (note-next-instruction vop :internal-error)
- (inst fsts fp-single-zero-tn 0 csp-tn)))))))
+ `(define-vop (,name)
+ (:args (x :scs (signed-reg)
+ :load-if (not (sc-is x signed-stack))
+ :target stack-temp))
+ (:arg-types signed-num)
+ (:results (y :scs (,to-sc)))
+ (:result-types ,to-type)
+ (:policy :fast-safe)
+ (:note "inline float coercion")
+ (:translate ,translate)
+ (:vop-var vop)
+ (:save-p :compute-only)
+ (:temporary (:scs (signed-stack) :from (:argument 0))
+ stack-temp)
+ (:temporary (:scs (single-reg) :to (:result 0) :target y)
+ fp-temp)
+ (:temporary (:scs (any-reg) :from (:argument 0)
+ :to (:result 0)) index)
+ (:generator 5
+ (let* ((nfp (current-nfp-tn vop))
+ (stack-tn
+ (sc-case x
+ (signed-stack
+ x)
+ (signed-reg
+ (storew x nfp (tn-offset stack-temp))
+ stack-temp)))
+ (offset (* (tn-offset stack-tn) n-word-bytes)))
+ (cond ((< offset (ash 1 4))
+ (inst flds offset nfp fp-temp))
+ ((and (< offset (ash 1 13))
+ (> offset 0))
+ (inst ldo offset zero-tn index)
+ (inst fldx index nfp fp-temp))
+ (t
+ (error "in vop ~s offset ~s is out-of-range" ',name offset)))
+ (note-this-location vop :internal-error)
+ (inst fcnvxf fp-temp y))))))
(frob %single-float/signed %single-float
single-reg single-float)
(frob %double-float/signed %double-float
double-reg double-float))
-
(macrolet ((frob (trans from-sc from-type inst note)
- `(define-vop (,(symbolicate trans "/" from-type))
- (:args (x :scs (,from-sc)
- :target fp-temp))
- (:results (y :scs (signed-reg)
- :load-if (not (sc-is y signed-stack))))
- (:arg-types ,from-type)
- (:result-types signed-num)
- (:translate ,trans)
- (:policy :fast-safe)
- (:note ,note)
- (:vop-var vop)
- (:save-p :compute-only)
- (:temporary (:scs (single-reg) :from (:argument 0)) fp-temp)
- (:temporary (:scs (signed-stack) :to (:result 0) :target y)
- stack-temp)
- (:temporary (:scs (any-reg) :from (:argument 0)
- :to (:result 0)) index)
- (:generator 3
- (let* ((nfp (current-nfp-tn vop))
- (stack-tn
- (sc-case y
- (signed-stack y)
- (signed-reg stack-temp)))
- (offset (* (tn-offset stack-tn) n-word-bytes)))
- (inst ,inst x fp-temp)
- (cond ((< offset (ash 1 4))
- (note-next-instruction vop :internal-error)
- (inst fsts fp-temp offset nfp))
- (t
- (inst ldo offset zero-tn index)
- (note-next-instruction vop :internal-error)
- (inst fstx fp-temp index nfp)))
- (unless (eq y stack-tn)
- (loadw y nfp (tn-offset stack-tn))))))))
+ `(define-vop (,(symbolicate trans "/" from-type))
+ (:args (x :scs (,from-sc)
+ :target fp-temp))
+ (:results (y :scs (signed-reg)
+ :load-if (not (sc-is y signed-stack))))
+ (:arg-types ,from-type)
+ (:result-types signed-num)
+ (:translate ,trans)
+ (:policy :fast-safe)
+ (:note ,note)
+ (:vop-var vop)
+ (:save-p :compute-only)
+ (:temporary (:scs (single-reg) :from (:argument 0)) fp-temp)
+ (:temporary (:scs (signed-stack) :to (:result 0) :target y)
+ stack-temp)
+ (:temporary (:scs (any-reg) :from (:argument 0)
+ :to (:result 0)) index)
+ (:generator 3
+ (let* ((nfp (current-nfp-tn vop))
+ (stack-tn
+ (sc-case y
+ (signed-stack y)
+ (signed-reg stack-temp)))
+ (offset (* (tn-offset stack-tn) n-word-bytes)))
+ (inst ,inst x fp-temp)
+ (cond ((< offset (ash 1 4))
+ (note-next-instruction vop :internal-error)
+ (inst fsts fp-temp offset nfp))
+ ((and (< offset (ash 1 13))
+ (> offset 0))
+ (inst ldo offset zero-tn index)
+ (note-next-instruction vop :internal-error)
+ (inst fstx fp-temp index nfp))
+ (t
+ (error "unary error, ldo offset too high")))
+ (unless (eq y stack-tn)
+ (loadw y nfp (tn-offset stack-tn))))))))
(frob %unary-round single-reg single-float fcnvfx "inline float round")
(frob %unary-round double-reg double-float fcnvfx "inline float round")
- (frob %unary-truncate single-reg single-float fcnvfxt
+ (frob %unary-truncate/single-float single-reg single-float fcnvfxt
"inline float truncate")
- (frob %unary-truncate double-reg double-float fcnvfxt
+ (frob %unary-truncate/double-float double-reg double-float fcnvfxt
"inline float truncate"))
-
(define-vop (make-single-float)
(:args (bits :scs (signed-reg)
- :load-if (or (not (sc-is bits signed-stack))
- (sc-is res single-stack))
- :target res))
+ :load-if (or (not (sc-is bits signed-stack))
+ (sc-is res single-stack))
+ :target res))
(:results (res :scs (single-reg)
- :load-if (not (sc-is bits single-stack))))
+ :load-if (not (sc-is bits single-stack))))
(:arg-types signed-num)
(:result-types single-float)
(:translate make-single-float)
(:generator 2
(let ((nfp (current-nfp-tn vop)))
(sc-case bits
- (signed-reg
- (sc-case res
- (single-reg
- (let ((offset (* (tn-offset temp) n-word-bytes)))
- (inst stw bits offset nfp)
- (cond ((< offset (ash 1 4))
- (inst flds offset nfp res))
- (t
- (inst ldo offset zero-tn index)
- (inst fldx index nfp res)))))
- (single-stack
- (inst stw bits (* (tn-offset res) n-word-bytes) nfp))))
- (signed-stack
- (sc-case res
- (single-reg
- (let ((offset (* (tn-offset bits) n-word-bytes)))
- (cond ((< offset (ash 1 4))
- (inst flds offset nfp res))
- (t
- (inst ldo offset zero-tn index)
- (inst fldx index nfp res)))))))))))
+ (signed-reg
+ (sc-case res
+ (single-reg
+ (let ((offset (* (tn-offset temp) n-word-bytes)))
+ (inst stw bits offset nfp)
+ (cond ((< offset (ash 1 4))
+ (inst flds offset nfp res))
+ ((and (< offset (ash 1 13))
+ (> offset 0))
+ (inst ldo offset zero-tn index)
+ (inst fldx index nfp res))
+ (t
+ (error "make-single-float error, ldo offset too large")))))
+ (single-stack
+ (inst stw bits (* (tn-offset res) n-word-bytes) nfp))))
+ (signed-stack
+ (sc-case res
+ (single-reg
+ (let ((offset (* (tn-offset bits) n-word-bytes)))
+ (cond ((< offset (ash 1 4))
+ (inst flds offset nfp res))
+ ((and (< offset (ash 1 13))
+ (> offset 0))
+ (inst ldo offset zero-tn index)
+ (inst fldx index nfp res))
+ (t
+ (error "make-single-float error, ldo offset too large")))))))))))
(define-vop (make-double-float)
(:args (hi-bits :scs (signed-reg))
- (lo-bits :scs (unsigned-reg)))
+ (lo-bits :scs (unsigned-reg)))
(:results (res :scs (double-reg)
- :load-if (not (sc-is res double-stack))))
+ :load-if (not (sc-is res double-stack))))
(:arg-types signed-num unsigned-num)
(:result-types double-float)
(:translate make-double-float)
(:vop-var vop)
(:generator 2
(let* ((nfp (current-nfp-tn vop))
- (stack-tn (sc-case res
- (double-stack res)
- (double-reg temp)))
- (offset (* (tn-offset stack-tn) n-word-bytes)))
+ (stack-tn (sc-case res
+ (double-stack res)
+ (double-reg temp)))
+ (offset (* (tn-offset stack-tn) n-word-bytes)))
(inst stw hi-bits offset nfp)
(inst stw lo-bits (+ offset n-word-bytes) nfp)
(cond ((eq stack-tn res))
- ((< offset (ash 1 4))
- (inst flds offset nfp res))
- (t
- (inst ldo offset zero-tn index)
- (inst fldx index nfp res))))))
-
-
-(define-vop (single-float-bits)
- (:args (float :scs (single-reg)
- :load-if (not (sc-is float single-stack))))
- (:results (bits :scs (signed-reg)
- :load-if (or (not (sc-is bits signed-stack))
- (sc-is float single-stack))))
- (:arg-types single-float)
- (:result-types signed-num)
- (:translate single-float-bits)
- (:policy :fast-safe)
- (:vop-var vop)
- (:temporary (:scs (signed-stack) :from (:argument 0) :to (:result 0)) temp)
- (:temporary (:scs (any-reg) :from (:argument 0) :to (:result 0)) index)
- (:generator 2
- (let ((nfp (current-nfp-tn vop)))
- (sc-case float
- (single-reg
- (sc-case bits
- (signed-reg
- (let ((offset (* (tn-offset temp) n-word-bytes)))
- (cond ((< offset (ash 1 4))
- (inst fsts float offset nfp))
- (t
- (inst ldo offset zero-tn index)
- (inst fstx float index nfp)))
- (inst ldw offset nfp bits)))
- (signed-stack
- (let ((offset (* (tn-offset bits) n-word-bytes)))
- (cond ((< offset (ash 1 4))
- (inst fsts float offset nfp))
- (t
- (inst ldo offset zero-tn index)
- (inst fstx float index nfp)))))))
- (single-stack
- (sc-case bits
- (signed-reg
- (inst ldw (* (tn-offset float) n-word-bytes) nfp bits))))))))
-
-(define-vop (double-float-high-bits)
- (:args (float :scs (double-reg)
- :load-if (not (sc-is float double-stack))))
- (:results (hi-bits :scs (signed-reg)
- :load-if (or (not (sc-is hi-bits signed-stack))
- (sc-is float double-stack))))
- (:arg-types double-float)
- (:result-types signed-num)
- (:translate double-float-high-bits)
- (:policy :fast-safe)
- (:vop-var vop)
- (:temporary (:scs (signed-stack) :from (:argument 0) :to (:result 0)) temp)
- (:temporary (:scs (any-reg) :from (:argument 0) :to (:result 0)) index)
- (:generator 2
- (let ((nfp (current-nfp-tn vop)))
- (sc-case float
- (double-reg
- (sc-case hi-bits
- (signed-reg
- (let ((offset (* (tn-offset temp) n-word-bytes)))
- (cond ((< offset (ash 1 4))
- (inst fsts float offset nfp :side 0))
- (t
- (inst ldo offset zero-tn index)
- (inst fstx float index nfp :side 0)))
- (inst ldw offset nfp hi-bits)))
- (signed-stack
- (let ((offset (* (tn-offset hi-bits) n-word-bytes)))
- (cond ((< offset (ash 1 4))
- (inst fsts float offset nfp :side 0))
- (t
- (inst ldo offset zero-tn index)
- (inst fstx float index nfp :side 0)))))))
- (double-stack
- (sc-case hi-bits
- (signed-reg
- (let ((offset (* (tn-offset float) n-word-bytes)))
- (inst ldw offset nfp hi-bits)))))))))
-
-(define-vop (double-float-low-bits)
- (:args (float :scs (double-reg)
- :load-if (not (sc-is float double-stack))))
- (:results (lo-bits :scs (unsigned-reg)
- :load-if (or (not (sc-is lo-bits unsigned-stack))
- (sc-is float double-stack))))
- (:arg-types double-float)
- (:result-types unsigned-num)
- (:translate double-float-low-bits)
- (:policy :fast-safe)
- (:vop-var vop)
- (:temporary (:scs (unsigned-stack) :from (:argument 0) :to (:result 0)) temp)
- (:temporary (:scs (any-reg) :from (:argument 0) :to (:result 0)) index)
- (:generator 2
- (let ((nfp (current-nfp-tn vop)))
- (sc-case float
- (double-reg
- (sc-case lo-bits
- (unsigned-reg
- (let ((offset (* (tn-offset temp) n-word-bytes)))
- (cond ((< offset (ash 1 4))
- (inst fsts float offset nfp :side 1))
- (t
- (inst ldo offset zero-tn index)
- (inst fstx float index nfp :side 1)))
- (inst ldw offset nfp lo-bits)))
- (unsigned-stack
- (let ((offset (* (tn-offset lo-bits) n-word-bytes)))
- (cond ((< offset (ash 1 4))
- (inst fsts float offset nfp :side 1))
- (t
- (inst ldo offset zero-tn index)
- (inst fstx float index nfp :side 1)))))))
- (double-stack
- (sc-case lo-bits
- (unsigned-reg
- (let ((offset (* (1+ (tn-offset float)) n-word-bytes)))
- (inst ldw offset nfp lo-bits)))))))))
-
+ ((< offset (ash 1 4))
+ (inst flds offset nfp res))
+ ((and (< offset (ash 1 13))
+ (> offset 0))
+ (inst ldo offset zero-tn index)
+ (inst fldx index nfp res))
+ (t
+ (error "make-single-float error, ldo offset too large"))))))
+
+(macrolet
+ ((float-bits (name reg rreg stack rstack atype anum side offset)
+ `(define-vop (,name)
+ (:args (float :scs (,reg)
+ :load-if (not (sc-is float ,stack))))
+ (:results (bits :scs (,rreg)
+ :load-if (or (not (sc-is bits ,rstack))
+ (sc-is float ,stack))))
+ (:arg-types ,atype)
+ (:result-types ,anum)
+ (:translate ,name)
+ (:policy :fast-safe)
+ (:vop-var vop)
+ (:temporary (:scs (signed-stack) :from (:argument 0) :to (:result 0)) temp)
+ (:temporary (:scs (any-reg) :from (:argument 0) :to (:result 0)) index)
+ (:generator 2
+ (let ((nfp (current-nfp-tn vop)))
+ (sc-case float
+ (,reg
+ (sc-case bits
+ (,rreg
+ (let ((offset (* (tn-offset temp) n-word-bytes)))
+ (cond ((< offset (ash 1 4))
+ ,@(if side
+ `((inst fsts float offset nfp :side ,side))
+ `((inst fsts float offset nfp))))
+ ((and (< offset (ash 1 13))
+ (> offset 0))
+ (inst ldo offset zero-tn index)
+ ,@(if side
+ `((inst fstx float index nfp :side ,side))
+ `((inst fstx float index nfp))))
+ (t
+ (error ,(format nil "~s,~s: inst-LDO offset too large"
+ name rreg))))
+ (inst ldw offset nfp bits)))
+ (,rstack
+ (let ((offset (* (tn-offset bits) n-word-bytes)))
+ (cond ((< offset (ash 1 4))
+ ,@(if side
+ `((inst fsts float offset nfp :side ,side))
+ `((inst fsts float offset nfp))))
+ ((and (< offset (ash 1 13))
+ (> offset 0))
+ (inst ldo offset zero-tn index)
+ ,@(if side
+ `((inst fstx float index nfp :side ,side))
+ `((inst fstx float index nfp))))
+ (t
+ (error ,(format nil "~s,~s: inst-LDO offset too large"
+ name rstack))))))))
+ (,stack
+ (sc-case bits
+ (,rreg
+ (inst ldw (* (+ (tn-offset float) ,offset) n-word-bytes)
+ nfp bits))))))))))
+ (float-bits single-float-bits single-reg signed-reg single-stack
+ signed-stack single-float signed-num nil 0)
+ (float-bits double-float-high-bits double-reg signed-reg
+ double-stack signed-stack double-float signed-num 0 0)
+ (float-bits double-float-low-bits double-reg unsigned-reg
+ double-stack unsigned-stack double-float unsigned-num 1 1))
-\f
;;;; Float mode hackery:
(sb!xc:deftype float-modes () '(unsigned-byte 32))
(defknown floating-point-modes () float-modes (flushable))
(defknown ((setf floating-point-modes)) (float-modes)
- float-modes)
+ float-modes)
(define-vop (floating-point-modes)
- (:results (res :scs (unsigned-reg)
- :load-if (not (sc-is res unsigned-stack))))
- (:result-types unsigned-num)
- (:translate floating-point-modes)
- (:policy :fast-safe)
- (:temporary (:scs (unsigned-stack) :to (:result 0)) temp)
- (:temporary (:scs (any-reg) :from (:argument 0) :to (:result 0)) index)
- (:vop-var vop)
+ (:results (res :scs (unsigned-reg)
+ :load-if (not (sc-is res unsigned-stack))))
+ (:result-types unsigned-num)
+ (:translate floating-point-modes)
+ (:policy :fast-safe)
+ (:temporary (:scs (unsigned-stack) :to (:result 0)) temp)
+ (:temporary (:scs (any-reg) :from (:argument 0) :to (:result 0)) index)
+ (:vop-var vop)
(:generator 3
- (let* ((nfp (current-nfp-tn vop))
- (stack-tn (sc-case res
- (unsigned-stack res)
- (unsigned-reg temp)))
- (offset (* (tn-offset stack-tn) n-word-bytes)))
- (cond ((< offset (ash 1 4))
- (inst fsts fp-single-zero-tn offset nfp))
- (t
- (inst ldo offset zero-tn index)
- (inst fstx fp-single-zero-tn index nfp)))
- (unless (eq stack-tn res)
- (inst ldw offset nfp res)))))
+ (let* ((nfp (current-nfp-tn vop))
+ (stack-tn (sc-case res
+ (unsigned-stack res)
+ (unsigned-reg temp)))
+ (offset (* (tn-offset stack-tn) n-word-bytes)))
+ (cond ((< offset (ash 1 4))
+ (inst fsts fp-single-zero-tn offset nfp))
+ ((and (< offset (ash 1 13))
+ (> offset 0))
+ (inst ldo offset zero-tn index)
+ (inst fstx fp-single-zero-tn index nfp))
+ (t
+ (error "floating-point-modes error, ldo offset too large")))
+ (unless (eq stack-tn res)
+ (inst ldw offset nfp res)))))
(define-vop (set-floating-point-modes)
- (:args (new :scs (unsigned-reg)
- :load-if (not (sc-is new unsigned-stack))))
- (:results (res :scs (unsigned-reg)))
- (:arg-types unsigned-num)
- (:result-types unsigned-num)
- (:translate (setf floating-point-modes))
- (:policy :fast-safe)
- (:temporary (:scs (unsigned-stack) :from (:argument 0) :to (:result 0)) temp)
- (:temporary (:scs (any-reg) :from (:argument 0) :to (:result 0)) index)
- (:vop-var vop)
+ (:args (new :scs (unsigned-reg)
+ :load-if (not (sc-is new unsigned-stack))))
+ (:results (res :scs (unsigned-reg)))
+ (:arg-types unsigned-num)
+ (:result-types unsigned-num)
+ (:translate (setf floating-point-modes))
+ (:policy :fast-safe)
+ (:temporary (:scs (unsigned-stack) :from (:argument 0) :to (:result 0)) temp)
+ (:temporary (:scs (any-reg) :from (:argument 0) :to (:result 0)) index)
+ (:vop-var vop)
(:generator 3
- (let* ((nfp (current-nfp-tn vop))
- (stack-tn (sc-case new
- (unsigned-stack new)
- (unsigned-reg temp)))
- (offset (* (tn-offset stack-tn) n-word-bytes)))
- (unless (eq new stack-tn)
- (inst stw new offset nfp))
- (cond ((< offset (ash 1 4))
- (inst flds offset nfp fp-single-zero-tn))
- (t
- (inst ldo offset zero-tn index)
- (inst fldx index nfp fp-single-zero-tn)))
- (inst ldw offset nfp res))))
-
+ (let* ((nfp (current-nfp-tn vop))
+ (stack-tn (sc-case new
+ (unsigned-stack new)
+ (unsigned-reg temp)))
+ (offset (* (tn-offset stack-tn) n-word-bytes)))
+ (unless (eq new stack-tn)
+ (inst stw new offset nfp))
+ (cond ((< offset (ash 1 4))
+ (inst flds offset nfp fp-single-zero-tn))
+ ((and (< offset (ash 1 13))
+ (> offset 0))
+ (inst ldo offset zero-tn index)
+ (inst fldx index nfp fp-single-zero-tn))
+ (t
+ (error "set-floating-point-modes error, ldo offset too large")))
+ (inst ldw offset nfp res))))
\f
;;;; Complex float VOPs
(define-vop (make-complex-single-float)
(:translate complex)
(:args (real :scs (single-reg) :target r)
- (imag :scs (single-reg) :to :save))
+ (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))))
+ :load-if (not (sc-is r complex-single-stack))))
(:result-types complex-single-float)
(:note "inline complex single-float creation")
(:policy :fast-safe)
(sc-case r
(complex-single-reg
(let ((r-real (complex-single-reg-real-tn r)))
- (unless (location= real r-real)
- (inst funop :copy real r-real)))
+ (unless (location= real r-real)
+ (inst funop :copy real r-real)))
(let ((r-imag (complex-single-reg-imag-tn r)))
- (unless (location= imag r-imag)
- (inst funop :copy imag r-imag))))
+ (unless (location= imag r-imag)
+ (inst funop :copy imag r-imag))))
(complex-single-stack
(let ((nfp (current-nfp-tn vop))
- (offset (* (tn-offset r) n-word-bytes)))
- (str-float real offset nfp)
- (str-float imag (+ offset n-word-bytes) nfp))))))
+ (offset (* (tn-offset r) n-word-bytes)))
+ (str-float real offset nfp)
+ (str-float imag (+ offset n-word-bytes) nfp))))))
(define-vop (make-complex-double-float)
(:translate complex)
(:args (real :scs (double-reg) :target r)
- (imag :scs (double-reg) :to :save))
+ (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))))
+ :load-if (not (sc-is r complex-double-stack))))
(:result-types complex-double-float)
(:note "inline complex double-float creation")
(:policy :fast-safe)
(sc-case r
(complex-double-reg
(let ((r-real (complex-double-reg-real-tn r)))
- (unless (location= real r-real)
- (inst funop :copy real r-real)))
+ (unless (location= real r-real)
+ (inst funop :copy real r-real)))
(let ((r-imag (complex-double-reg-imag-tn r)))
- (unless (location= imag r-imag)
- (inst funop :copy imag r-imag))))
+ (unless (location= imag r-imag)
+ (inst funop :copy imag r-imag))))
(complex-double-stack
(let ((nfp (current-nfp-tn vop))
- (offset (* (tn-offset r) n-word-bytes)))
- (str-float real offset nfp)
- (str-float imag (+ offset (* 2 n-word-bytes)) nfp))))))
-
+ (offset (* (tn-offset r) n-word-bytes)))
+ (str-float real offset nfp)
+ (str-float imag (+ offset (* 2 n-word-bytes)) nfp))))))
(define-vop (complex-single-float-value)
(:args (x :scs (complex-single-reg) :target r
- :load-if (not (sc-is x complex-single-stack))))
+ :load-if (not (sc-is x complex-single-stack))))
(:arg-types complex-single-float)
(:results (r :scs (single-reg)))
(:result-types single-float)
(sc-case x
(complex-single-reg
(let ((value-tn (ecase slot
- (:real (complex-single-reg-real-tn x))
- (:imag (complex-single-reg-imag-tn x)))))
- (unless (location= value-tn r)
- (inst funop :copy value-tn r))))
+ (:real (complex-single-reg-real-tn x))
+ (:imag (complex-single-reg-imag-tn x)))))
+ (unless (location= value-tn r)
+ (inst funop :copy value-tn r))))
(complex-single-stack
(ld-float (* (+ (ecase slot (:real 0) (:imag 1)) (tn-offset x))
- n-word-bytes)
- (current-nfp-tn vop) r)))))
+ n-word-bytes)
+ (current-nfp-tn vop) r)))))
(define-vop (realpart/complex-single-float complex-single-float-value)
(:translate realpart)
(define-vop (complex-double-float-value)
(:args (x :scs (complex-double-reg) :target r
- :load-if (not (sc-is x complex-double-stack))))
+ :load-if (not (sc-is x complex-double-stack))))
(:arg-types complex-double-float)
(:results (r :scs (double-reg)))
(:result-types double-float)
(sc-case x
(complex-double-reg
(let ((value-tn (ecase slot
- (:real (complex-double-reg-real-tn x))
- (:imag (complex-double-reg-imag-tn x)))))
- (unless (location= value-tn r)
- (inst funop :copy value-tn r))))
+ (:real (complex-double-reg-real-tn x))
+ (:imag (complex-double-reg-imag-tn x)))))
+ (unless (location= value-tn r)
+ (inst funop :copy value-tn r))))
(complex-double-stack
(ld-float (* (+ (ecase slot (:real 0) (:imag 2)) (tn-offset x))
- n-word-bytes)
- (current-nfp-tn vop) r)))))
+ n-word-bytes)
+ (current-nfp-tn vop) r)))))
(define-vop (realpart/complex-double-float complex-double-float-value)
(:translate realpart)