The store into buf[] dependency doesn't stop this, after unrolling:
asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base));
buf64[i++] = x;
asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base));
buf64[i++] = x;
from being reordered as this
asm volatile ("ldrd\t%0, [%1]" : "=&r" (x2) : "r" (io_base));
asm volatile ("ldrd\t%0, [%1]" : "=&r" (x1) : "r" (io_base));
buf64[i++] = x1;
buf64[i++] = x2;
because the asm doesn't depend on memory, just register inputs and
outputs;
I'm not sure what you mean about the volatile stopping gcc from
treating the asm as a pure function. Is that meaning of volatile in
the asm documentation? (volatile on asm doesn't mean the same as
volatile on a function, or volatile on a pointer).
'Q'
A memory reference where the exact address is in a single
register (''m'' is preferable for 'asm' statements)
If 'r' is good enough for io_base, 'Q' should be good enough for *io_base.
-- Jamie
--