Hi y'all !
The ARM specs are a little too dry for me when cycle latency is concerned.
Im interlacing many reads/writes (most uncached) and I wonder how exactly to predict wait clock cycle for RAM access, register usage, and such things.
Any known doc out there for the ARMs 920/940 ?
I'm pretty sure that uncached memory reads stall the fetch pipeline stage for a LONG time, though that time is not really a function of the ARM itself. This delay makes other issues pretty unimportant. But ignoring that, I think a basic rule of thumb is that you need to wait 2 cycles before using a loaded value, and brances are bad (3 cycles I think plus the pipeline flush). I invested in a great book about the ARM that goes into a lot of detail about this (I don't have it handy and forget the title, I can look at it later if you'd like). It's not cheap though.
The best book I know for this is
ARM System Developer's Guide : Designing and Optimizing System Software; it really contains everything you need to develop hardcore ARM stuff for this platform and in general. Anyway, cycle-counting wise it's almost exactly as Dzz says; uncached loads will stall until the value is loaded (exact latency depends on memory speed, obviously), a cached load will have a one cycle latency unless it's a byte, half-word (16-bits on an ARM), or signed load in which case it'll take another cycle to sign-extend or clear it. Using the value from a load in the next instruction will add extra cycles into the pipeline to interlock. Branches are indeed 3 cycles plus a pipeline flush.
The other ones to be wary of:
a register-based shift (e.g. mov r0,r0,lsr r1) costs an extra cycle.
a multiply instruction's timing is based on the value in the right hand register, so if you know that r1 is always > r0 then do mul r2,r1,r0 and not mul r2,r0,r1 (actual penalty depends on the where the first bit that differs from the sign bit is). I can dump a table here if it's not in the ARM9 manual.
And the corollary, optimisations:
a 32x32=64-bit multiply costs only one more cycle than a 32x32=32-bit multiply
an MLA / xMLAL costs the same as a MUL / xMULL
For those of us that are used to StrongARMs (and XScale), the ARM9 implementation is quite clean regarding penalties.
The only problem is that existing heavily StrongARM/XScale optimised stuff is not optimised for the ARM9. Ho hum.