This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: arm inline assembly constraint for coprocessor registers


On Wed, 2009-04-08 at 17:14 -0700, Ian Lance Taylor wrote:
> John Breitenbach <breiten@lexmark.com> writes:
> 
> > In the following inline assembly code, my input parameters need to be
> > prefixed with "c" rather than "r".
> > I.e. "c0" can be considered an alias for r0, and "c1" for r1, etc.  I
> > found several instances of inline assembly
> > in the linux kernel which punted when it came to this - assuming that
> > the function doesn't get inlined, and they
> > hard-code c0 and c1 in cases similar to the one below.
> >
> > I've found current documentation on arm-specific constraints, which
> > don't mention coprocessor registers,
> > and I tried "c" as below, hoping that it would work.  The "mrc"
> > instruction syntax requires "c" registers for its
> > source operands, although they are actually the regular registers.
> >
> > Any advice?
> >
> > unsigned foo( unsigned a, unsigned b)
> > {
> >  int rc;
> >  __asm__( "mrc p6,0,%0,%1,%2,5": "=r"(rc): "c"(a),"c"(b));
> >  return( rc);
> > }
> >
> > if not inlined, this needs to assemble as "mrc p6,0,r0,c0,c1,5", but I
> > really don't want to hard-code c0 and c1"
> 
> The "c" constraint means the condition code register.  That's not what
> you want.
> 
> You seem to want to ask gcc to allocate a and b to coprocessor
> registers.  That doesn't make much sense.  gcc doesn't know anything
> about the coprocessor registers and it won't allocate values to them.
> 
> If you use an "r" constraint, then gcc will arrange for a and b to be
> loaded into some general register.  If these really are the same as the
> coprocessor registers in your mrc instruction--if storing, e.g., a into
> r8 means that mrc will access it as cr8--then just write
> 
>   __asm__( "mrc p6,0,%0,c%1,c%2,5": "=r"(rc): "r"(a), "r"(b));
> 
> This will produce cr8, which I think is what gas expects.
> 
> Otherwise, I don't know what you want to do.

It certainly isn't that...

Co-processor registers are distinct from the core registers.  The only
co-processors that GCC knows about are:
The VFP/Neon from ARM.
Intel's Wireless MMX extensions
Cirrus' Maverick extensions
(and legacy FPA)

In other cases GCC has no knowledge of any additional registers you
might have, and there's no way, short of modifying the compiler, to
describe them to the compiler.  Without that information, the compiler's
register allocator cannot deal with them.

So your only option here is to hard-code the register numbers into your
instruction mnemonics, or port GCC to support your co-processor (be
warned, that's a non-trivial task).

R.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]