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.