Re: [arm-gnu] Explicit registers constraints in Inline assembler

    * To: Paul Brook <paul@xxxxxxxxxxxxxxxx>
    * Subject: Re: [arm-gnu] Explicit registers constraints in Inline assembler
    * From: Jon Medhurst <codesourcery@xxxxxxxxxxxxxx>
    * Date: Tue, 11 Apr 2006 21:25:46 +0100

Paul Brook wrote:


        What I am currently using is something like...

           inline int ASysCall(int arg0, int arg1)
               {
               register int r0 asm("r0") = arg0;
               register int r1 asm("r1") = arg1;
               asm volatile("swi %0" : : "i" (ASysCallEnum), "r"(r0), "r"(r1));
               asm volatile("" : : : "r0", "r1", "r2", "r3", "r12", "lr");
               return r0;
               }

        but in a reply to a post on CodeSourcery titled "Re: [arm-gnu] Using
        separate interrupt handler registers from C? (ARM7)"
        Paul Brook said

        "gcc does not guarantee that the value will always be held in the
        register, and may
        emilinate "dead" stores to that variable. The only time gcc guarantees the
        register will be used is as an explicit argument to an inline assembly
        fragment. "

        This leads me to surmise that there may be some magic sytax that I can't
        find. Is there any documents/FAQs that are relevent?

    GCC assembly sytax is documented here.
    http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Extended-Asm.html#Extended-Asm

        BTW, the second empty asm statement is so I can specify clobbered
        registers. GCC doesn't  like me specifying these in the first asm
        statement; it says something like "error: asm-specifier for variable
        `r0' conflicts with asm clobber list", - but if I don't specify it as
        clobbered it doesn't save the values it has put in these registers. (!)

    If you modify asm inputs you need to list them as outputs and use numbered constraints for the corresponding inputs. ie:

    inline int ASysCall(int arg0, int arg1)
    {
     register int r0 asm("r0") = arg0;
     register int r1 asm("r1") = arg1;
     asm volatile("swi %0"
    	: "=r" (r0), "=r" (r1)
    	: "i" (ASysCallEnum), "0"(r0), "1"(r1)
    	: "r2", "r3", "r12", "lr");
     return r0;
    }

    The code you have works by chance, and could easily break.

    Paul

Many thanks. The documentaion you pointed to contains a lot of useful information which answers all of my questions. This documentation is the same as ships with the CodeSourcery distribution, which I *had* looked at prior to posting my question; however I had not read it carefully enough to realise that it much updated from an old version I was already familiar with.

I must remember not only to RTFM, but do so with the latest manual ;-)

Thanks again

--
Jon


