inline assembly
Hi,
When doing inline assembly, is there a way to get the compiler to
assign "extra" (one not specified for inputs and outputs) registers? In the following:
__asm__ __volatile__ (
"addi 5,%1,-1\n"
"andc 5,%1,5\n"
"cntlzw 5,5\n"
"subfic %0,5,31":
"=r"(j):
"r"(i)
);Can I get the compiler to choose a register for r5?
kevin
Quoted 14 lines · Kevin Diggs
Hi,
When doing inline assembly, is there a way to get the compiler to
assign "extra" (one not specified for inputs and outputs) registers? In the following:__asm__ __volatile__ ( "addi 5,%1,-1\n" "andc 5,%1,5\n" "cntlzw 5,5\n" "subfic %0,5,31": "=r"(j): "r"(i) );
Quoted 1 line
Can I get the compiler to choose a register for r5?
Yes, like this:
int tmp;
asm volatile("addi %1, %2, -1;"
"andc %1, %2, %1;"
"cntlzw %1, %1;"
"subfic %0, %1, 31" : "=r" (j), "=&r" (tmp) : "r" (i));However, it'd be better to let the compiler do more, by just using the existing cntlzw() function.
-Scott
Quoted 6 lines · Scott Wood
int tmp;
asm volatile("addi %1, %2, -1;"
"andc %1, %2, %1;" "cntlzw %1, %1;" "subfic %0, %1, 31" : "=r" (j), "=&r" (tmp) : "r" (i));
Registers are usually assumed to be 'long' in size, so I'd recommend using that rather than 'int' for tmp, though I suspect it'll make little difference (except, perhaps on x86 where you can partially use registers).
Quoted 2 lines
However, it'd be better to let the compiler do more, by just using the existing
cntlzw()function.
Look in include/asm-powerpc/bitops.h. There are examples of the things you're trying to do:
static __inline__ __attribute__((const))
int __ilog2(unsigned long x)
{
int lz;
asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x));
return BITS_PER_LONG - 1 - lz;
}
static __inline__ int __ffs(unsigned long x)
{
return __ilog2(x & -x);
}Where:
asm-compat.h:79:#define PPC_CNTLZL stringify_in_c(cntlzd)
asm-compat.h:100:#define PPC_CNTLZL stringify_in_c(cntlzw)
Depending on whether you're in 32-bit mode or 64-bit mode.
David
Quoted 4 lines · David Howells
Quoted 2 lines · Scott Wood
int tmp;
Quoted 8 lines
Quoted 4 lines
asm volatile("addi %1, %2, -1;"
"andc %1, %2, %1;" "cntlzw %1, %1;" "subfic %0, %1, 31" : "=r" (j), "=&r" (tmp) : "r" (i));Registers are usually assumed to be 'long' in size, so I'd recommend using that rather than 'int' for tmp, though I suspect it'll make little difference (except, perhaps on x86 where you can partially use registers).
I had originally written that as long, but I changed it since the asm code is explicitly assuming 32-bit. It's more documentation than anything else.
-Scott