- (complex-reg (symbolicate "COMPLEX-" float-type "-REG"))
- (real-reg (symbolicate float-type "-REG"))
- (c-type (symbolicate "COMPLEX-" float-type "-FLOAT"))
- (real-part (symbolicate "COMPLEX-" float-type "-REG-REAL-TN"))
- (imag-part (symbolicate "COMPLEX-" float-type "-REG-IMAG-TN")))
- `(define-vop (,vop-name)
- (:args (x :scs (,complex-reg))
- (y :scs (,complex-reg)))
- (:results (r :scs (,complex-reg)))
- (:arg-types ,c-type ,c-type)
- (:result-types ,c-type)
- (:policy :fast-safe)
- (:note "inline complex float division")
- (:translate /)
- (:temporary (:sc ,real-reg) ratio)
- (:temporary (:sc ,real-reg) den)
- (:temporary (:sc ,real-reg) temp-r)
- (:temporary (:sc ,real-reg) temp-i)
- (:generator ,cost
- (let ((xr (,real-part x))
- (xi (,imag-part x))
- (yr (,real-part y))
- (yi (,imag-part y))
- (rr (,real-part r))
- (ri (,imag-part r))
- (bigger (gen-label))
- (done (gen-label)))
- (,@fabs ratio yr)
- (,@fabs den yi)
- (inst ,fcmp ratio den)
- #!-:sparc-v9 (inst nop)
- (inst fb :ge bigger)
- (inst nop)
- ;; The case of |yi| <= |yr|
- (inst ,fdiv ratio yi yr) ; ratio = yi/yr
- (inst ,fmul den ratio yi)
- (inst ,fadd den den yr) ; den = yr + (yi/yr)*yi
-
- (inst ,fmul temp-r ratio xi)
- (inst ,fadd temp-r temp-r xr) ; temp-r = xr + (yi/yr)*xi
- (inst ,fdiv temp-r temp-r den)
-
- (inst ,fmul temp-i ratio xr)
- (inst ,fsub temp-i xi temp-i) ; temp-i = xi - (yi/yr)*xr
- (inst b done)
- (inst ,fdiv temp-i temp-i den)
-
- (emit-label bigger)
- ;; The case of |yi| > |yr|
- (inst ,fdiv ratio yr yi) ; ratio = yr/yi
- (inst ,fmul den ratio yr)
- (inst ,fadd den den yi) ; den = yi + (yr/yi)*yr
-
- (inst ,fmul temp-r ratio xr)
- (inst ,fadd temp-r temp-r xi) ; temp-r = xi + xr*(yr/yi)
- (inst ,fdiv temp-r temp-r den)
-
- (inst ,fmul temp-i ratio xi)
- (inst ,fsub temp-i temp-i xr) ; temp-i = xi*(yr/yi) - xr
- (inst ,fdiv temp-i temp-i den)
-
- (emit-label done)
- (unless (location= temp-r rr)
- (,@fmov rr temp-r))
- (unless (location= temp-i ri)
- (,@fmov ri temp-i))
- ))))))
+ (complex-reg (symbolicate "COMPLEX-" float-type "-REG"))
+ (real-reg (symbolicate float-type "-REG"))
+ (c-type (symbolicate "COMPLEX-" float-type "-FLOAT"))
+ (real-part (symbolicate "COMPLEX-" float-type "-REG-REAL-TN"))
+ (imag-part (symbolicate "COMPLEX-" float-type "-REG-IMAG-TN")))
+ `(define-vop (,vop-name)
+ (:args (x :scs (,complex-reg))
+ (y :scs (,complex-reg)))
+ (:results (r :scs (,complex-reg)))
+ (:arg-types ,c-type ,c-type)
+ (:result-types ,c-type)
+ (:policy :fast-safe)
+ (:note "inline complex float division")
+ (:translate /)
+ (:temporary (:sc ,real-reg) ratio)
+ (:temporary (:sc ,real-reg) den)
+ (:temporary (:sc ,real-reg) temp-r)
+ (:temporary (:sc ,real-reg) temp-i)
+ (:generator ,cost
+ (let ((xr (,real-part x))
+ (xi (,imag-part x))
+ (yr (,real-part y))
+ (yi (,imag-part y))
+ (rr (,real-part r))
+ (ri (,imag-part r))
+ (bigger (gen-label))
+ (done (gen-label)))
+ (,@fabs ratio yr)
+ (,@fabs den yi)
+ (inst ,fcmp ratio den)
+ (unless (member :sparc-v9 *backend-subfeatures*)
+ (inst nop))
+ (inst fb :ge bigger)
+ (inst nop)
+ ;; The case of |yi| <= |yr|
+ (inst ,fdiv ratio yi yr) ; ratio = yi/yr
+ (inst ,fmul den ratio yi)
+ (inst ,fadd den den yr) ; den = yr + (yi/yr)*yi
+
+ (inst ,fmul temp-r ratio xi)
+ (inst ,fadd temp-r temp-r xr) ; temp-r = xr + (yi/yr)*xi
+ (inst ,fdiv temp-r temp-r den)
+
+ (inst ,fmul temp-i ratio xr)
+ (inst ,fsub temp-i xi temp-i) ; temp-i = xi - (yi/yr)*xr
+ (inst b done)
+ (inst ,fdiv temp-i temp-i den)
+
+ (emit-label bigger)
+ ;; The case of |yi| > |yr|
+ (inst ,fdiv ratio yr yi) ; ratio = yr/yi
+ (inst ,fmul den ratio yr)
+ (inst ,fadd den den yi) ; den = yi + (yr/yi)*yr
+
+ (inst ,fmul temp-r ratio xr)
+ (inst ,fadd temp-r temp-r xi) ; temp-r = xi + xr*(yr/yi)
+ (inst ,fdiv temp-r temp-r den)
+
+ (inst ,fmul temp-i ratio xi)
+ (inst ,fsub temp-i temp-i xr) ; temp-i = xi*(yr/yi) - xr
+ (inst ,fdiv temp-i temp-i den)
+
+ (emit-label done)
+ (unless (location= temp-r rr)
+ (,@fmov rr temp-r))
+ (unless (location= temp-i ri)
+ (,@fmov ri temp-i))
+ ))))))