************************************************************************
**            Written by Dino Papararo            21-October-2001
**
**  FUNCTION
**
**    Mandel4PPC -- perform Z = (Z²)² + C iteration.
**
**  SYNOPSIS
**
**    ULONG Mandel4PPC (ULONG Iterations,long double Cre,long double Cim)
**
**
**  This function tests if a point belongs or not at mandelbrot's set
**
**  Optimized for pipelines of PPC processors.
**
**  r3:Iterations
**  f1:Cre f2:Cim f3:Zr f4:Zi f5:Tmp1/Zr2 f6:Tmp2/Zi2/zi4 f7:Dist f8:MaxDist
****************************************************************************


                include powerpc/ppcmacros.i
                include powerpc/powerpc.i

                xref _PowerPCBase

                xdef _Mandel4PPC


                section code

                cpu POWERPC

_Mandel4PPC

                 prolog             ; start

                 lf     f8,Radius   ; MaxDist = Radius
                 fmr    f4,f2       ; Zi = Cim
                 fmr    f3,f1       ; Zr = Cre

                 mtctr  r3          ; Load Iterations into counter

************************************************************************
* HAAGE&PARTNER PPC ASM function is the fastest I have ever seen and
* without any pipeline wait state for the maximum speeed on PPC.
* Recoded by Dino Papararo with small changes.
************************************************************************
*
*                 fsub   f8,f8,f1    ; MaxDist = Radius - Cre
*.Loop
*                 fmsub  f6,f4,f4,f1 ; Tmp2 = Zi^2 - Cre
*                 fadd   f5,f3,f3    ; Tmp1 = 2 * Zr
*                 fmadd  f7,f3,f3,f6 ; Dist = Zr^2 + Tmp2
*                 fmsub  f3,f3,f3,f6 ; Zr = Zr^2 - Tmp2
*                 fmadd  f4,f4,f5,f2 ; Zi = Tmp1 * Zi + Cim
*                 fcmpu  f7,f8       ; if Dist > MaxDist and
*                 bdnzf+ GT,.Loop    ; Iterations != 0 goto Loop
*
************************************************************************
* Dino Papararo MandelBrot PPC ASM function for rendering Mandelbrot set
* a bit slower than HAAGE&PARTNER one, but simplest, more elegant and
* without any pipeline wait state too :-))

**  r3:Iterations
**  f1:Cre f2:Cim f3:Zr f4:Zi f5:Tmp1/Zr2 f6:Tmp2/Zi2/zi4 f7:Dist f8:MaxDist
****************************************************************************
.Loop
                 fmul   f6,f4,f4    ; zi2 = zi * zi
                 fmul   f4,f3,f4    ; zi = zr * zi
                 fmsub  f3,f3,f3,f6 ; zr2 = zr * zr - zi2
                 fadd   f4,f4,f4    ; zi = zi + zi
                 fmul   f6,f4,f4    ; zi4 = zi * zi
                 fadd   f4,f4,f4    ; zi = zi + zi
                 fmadd  f7,f3,f3,f6 ; dist = zr * zr + zi2
                 fmsub  f5,f3,f3,f6 ; zr4 = zr * zr - zi2
                 fmadd  f4,f3,f4,f2 ; zi = zr * zi + Cim
                 fadd   f3,f5,f1    ; zr += Cre
                 fcmpu  f7,f8       ; compare dist with radius
                 bdnzf+ GT,.Loop    ; if maxdist > radius or --iterations != 0 goto Loop
************************************************************************

.End

                 mfctr  r3          ; Store Iterations from counter

                 epilog             ; end


                section data

Radius          dc.d   4.0
