************************************************************************
**            Written by Dino Papararo            23-Apr-2001
**
**  FUNCTION
**
**    MandelPPC -- perform Z = Z^2 + C iteration.
**
**  SYNOPSIS
**
**    ULONG MandelPPC (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 f7:Dist f8:MaxDist
*************************************************************************


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

                xref _PowerPCBase

                xdef _MandelPPC


                section code

                cpu POWERPC

_MandelPPC

                 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 :-))
*
*.Loop
*                 fmul   f6,f4,f4    ; zi2 = zi * zi
*                 fadd   f4,f4,f4    ; zi = zi + zi
*                 fmadd  f7,f3,f3,f6 ; dist = zr * zr + zi2
*                 fmsub  f5,f3,f3,f6 ; zr = 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