Given the following code:

Loop:	LD   f0,0(r1)	; f0 = vector element
	ADDD f4,f0,f2	; add scalar from f2
	SD   f4,0(r1)	; store result
	SUBI r1,r1,8	; decrement pointer 8bytes
	BNEZ r1,loop	; branch r1 != zero
	NOP		; branch delay slot

Assuming the following latencies:  3 cycles between FP ALU Ops, 2 between FP
ALU OP and Store double, 1 between load double and FP ALU OP, 0 between
Load Double and Store double, these latencies are when there are data
dependencies.
Here is the way it would execute without any modifications:

Loop:	LD   f0,0(r1)	; f0 = vector element
	stall
	ADDD f4,f0,f2	; add scalar from f2
	stall
	stall
	SD   f4,0(r1)	; store result
	SUBI r1,r1,#8	; decrement pointer 8bytes
	stall
	BNEZ r1,loop	; branch r1 != zero
	stall		; branch delay slot

Takes 10 clocks.


We can reorder the code (schedule it) to reduce some of the stalls:

Loop:	LD   f0,0(r1)	; f0 = vector element
	stall
	ADDD f4,f0,f2	; add scalar from f2
	stall
	stall
	SUBI r1,r1,8	; decrement pointer 8bytes
	BNEZ r1,loop	; branch r1 != zero
->	SD   8(r1),f4	; store result

Now it takes 8 clocks.  

What about "unrolling" the loop?

Loop:	LD   f0,0(r1)	; f0 = vector element
	ADDD f4,f0,f2	; add scalar from f2
	SUBI r1,r1,8	; decrement pointer 8bytes
	BNEZ r1,loop	; branch r1 != zero
	SD   8(r1),f4	; store result
	LD   f0,0(r1)	; f0 = vector element
	ADDD f4,f0,f2	; add scalar from f2
	SUBI r1,r1,8	; decrement pointer 8bytes
	BNEZ r1,loop	; branch r1 != zero
	SD   8(r1),f4	; store result
	LD   f0,0(r1)	; f0 = vector element
	ADDD f4,f0,f2	; add scalar from f2
	SUBI r1,r1,8	; decrement pointer 8bytes
	BNEZ r1,loop	; branch r1 != zero
	SD   8(r1),f4	; store result
	LD   f0,0(r1)	; f0 = vector element
	ADDD f4,f0,f2	; add scalar from f2
	SUBI r1,r1,8	; decrement pointer 8bytes
	BNEZ r1,loop	; branch r1 != zero
	SD   8(r1),f4	; store result

Removing the unnecessary SUBI's and BNEZ's, loop becomes

Loop:	LD   f0,0(r1)	; f0 = vector element
	ADDD f4,f0,f2	; add scalar from f2
	SD   0(r1),f4	; store result
	LD   f0,-8(r1)	; f0 = vector element
	ADDD f4,f0,f2	; add scalar from f2
	SD   -8(r1),f4	; store result
	LD   f0,-16(r1)	; f0 = vector element
	ADDD f4,f0,f2	; add scalar from f2
	SD   -16(r1),f4	; store result
	LD   f0,-24(r1)	; f0 = vector element
	ADDD f4,f0,f2	; add scalar from f2
	SD   -24(r1),f4	; store result
	SUBI r1,r1,#32
	BNEZ r1,loop	; patch up here.


Now we need to watch for output and anti-dependencies, which are dependencies 
which do not transmit any data values between them.  These are different than 
data (true) dependencies, where there is data moving between.

We can also remove the subtract and branch's in this case, by changing the
immediate value in the SD field.

Loop:	LD   f0,0(r1)	; f0 = vector element
						Arrow from f0 to f0 (data)
						Arrow from f0 to next f0 (name)
	ADDD f4,f0,f2	; add scalar from f2
	SD   0(r1),f4	; store result
	LD   f0,-8(r1)	; f0 = vector element
	ADDD f4,f0,f2	; add scalar from f2
	SD   -8(r1),f4	; store result
	LD   f0,-16(r1)	; f0 = vector element
	ADDD f4,f0,f2	; add scalar from f2
	SD   -16(r1),f4	; store result
	LD   f0,-24(r1)	; f0 = vector element
	ADDD f4,f0,f2	; add scalar from f2
	SD   -24(r1),f4	; store result
	SUBI r1,r1,#32
	BNEZ r1,loop	; patch up here.


Becomes

Loop:	LD   f0,0(r1)	; f0 = vector element
	stall
	ADDD f4,f0,f2	; add scalar from f2
	stall
	stall
	SD   0(r1),f4	; store result
	LD   f6,-8(r1)	; f0 = vector element
	stall
	ADDD f8,f6,f2	; add scalar from f2
	stall
	SD   -8(r1),f8	; store result
	stall
	LD   f10,-16(r1)	; f0 = vector element
	stall
	ADDD f12,f10,f2	; add scalar from f2
	stall
	stall
	SD   -16(r1),f12	; store result
	LD   f14,-24(r1)	; f0 = vector element
	stall
	ADDD f16,f14,f2	; add scalar from f2
	stall
	stall
	SD   -24(r1),f16	; store result
	SUBI r1,r1,#32
	BNEZ r1,loop	; patch up here.
	NOP

Now we have 15+4(1+2) = 27 cycles.

Now - schedule code minimize stalls:

Loop:	LD   f0,0(r1)	; f0 = vector element
	LD   f6,-8(r1)	; f0 = vector element
	LD   f10,-16(r1)	; f0 = vector element
	LD   f14,-24(r1)	; f0 = vector element
	ADDD f4,f0,f2	; add scalar from f2
	ADDD f8,f6,f2	; add scalar from f2
	ADDD f12,f10,f2	; add scalar from f2
	ADDD f16,f14,f2	; add scalar from f2
	SD   0(r1),f4	; store result
	SD   -8(r1),f8	; store result
	SD   -16(r1),f12	; store result
	SUBI r1,r1,#32
	BNEZ r1,loop	; patch up here.
	SD   8(r1),f16	; store result

14 cycles, or 3.5 cycles per iteration.  Pretty slick!!

