Avoid certain registers in inline assembly

Andrew Haley aph@redhat.com
Mon Jul 12 10:15:00 GMT 2010


On 07/12/2010 10:40 AM, Andy Gibbs wrote:
> Hi,
> 
> I am using GCC 4.4.4 for PowerPC (6xx series), and I've come across a
> bug in some software that I'm trying to solve the best way.
> 
> The problem came to light around some atomic operator code, such as the
> following:
> 
> static inline int atomic_post_inc(volatile int* ptr)
> {
> register int temp1, temp2;
> asm volatile (
>  "1: lwarx   %0, 0, %2 \n"
>  "   mr      %1, %0 \n"
>  "   addi    %0, %0, 1 \n"
>  "   stwcx.  %0, 0, %2 \n"
>  "   bne-    1b \n"
>   : "=&r" (temp1), "=&r" (temp2) : "r" (ptr) : "cc", "memory"
>  );
> 
> return temp2;
> }
> 
> The problem comes when using -O1, -O2 or -O3 when GCC chooses register
> r0 for 'temp1'.  This changes the addi line to 'addi 0, 0, 1' but on the
> PowerPC platform this particular instruction has a special meaning for
> '0' as the second parameter, so basically rather than adding 1 to
> register 0, it instead sets register 0 to 1.  Obviously this breaks the
> functionality of this code.
> 
> A simple solution in this case is to change the 'addi' opcode to 'addic'
> which doesn't have this special meaning for '0' as the second parameter,
> and add "xer" to the list of clobbered registers.
> 
> All well and good in this example, but there are other places where such
> a simple instruction alteration is not the answer.  What I was wondering
> is, is there a way to tell GCC to avoid certain registers, in particular
> to avoid register r0, when assigning registers for inline assembly?
> 
> I know it is possible to directly define which register a temporary
> variable would have (e.g. by "register int temp1 asm ("r5");" for
> example), but this then means that GCC is not free to choose the best
> register in order to avoid unnecessary register copy instructions.
> 
> Is it therefore possible to tell GCC simply to just avoid using a
> particular register?

You need to specify a base register, not a general register.

  : "=&b" (temp1), "=&r" (temp2) : "r" (ptr) : "cc", "memory"

Andrew.



More information about the Gcc-help mailing list