inline assembly

4 messages, 3 authors, 2008-06-05 · open the first message on its own page

inline assembly

From: Kevin Diggs <hidden>
Date: 2008-06-04 19:38:06

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

Re: inline assembly

From: Scott Wood <hidden>
Date: 2008-06-04 19:45:11

Kevin Diggs wrote:
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?
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

Re: inline assembly

From: David Howells <dhowells@redhat.com>
Date: 2008-06-05 10:45:22

Scott Wood [off-list ref] wrote:
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).
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

Re: inline assembly

From: Scott Wood <hidden>
Date: 2008-06-05 16:52:42

On Thu, Jun 05, 2008 at 11:44:51AM +0100, David Howells wrote:
Scott Wood [off-list ref] wrote:
quoted
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).
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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help