I'm just wondering If I do the following:
{
register uint32_t v1 asm("r6"), v2 asm("r7");
register uint32_t v3 asm("r8"), v4 asm("r10");
asm volatile (
/* Move data */
" ldm %[src], {%[v1],%[v2],%[v3],%[v4]};"
" stm %[dst], {%[v1],%[v2],%[v3],%[v4]};"
: /* output constraints */
"=m"(*(uint64_t (*)[2])dst),
[v1]"=&r"(v1), [v2]"=&r"(v2),
[v3]"=&r"(v3), [v4]"=&r"(v4)
: /* input constraints */
"m"(*(const uint64_t (*)[2])src),
[dst]"r"(read_dst),
[src]"r"((const uint64_t* )src)
: /* clobber constraints */
);
}
is v1 guaranteed to be at r6, or is the compiler free to make an optimization to use another register? Is there a way to tie a name to a particular register? (without manually specify %r6 everywhere?)
Also, is there a difference between using an output constraint vs a clobber constraint for a temporary variable? (assuming it is not referenced after the inline assembly call?)
I'm using gcc and clang, so a solution would have to work for both. This is of course a simplified example for the purposes of posting a question.