Subject: Re: inline assembly & r0 SOS

From: Andreas Schwab <[email-masked]>
Date: Wed, 06 Aug 2008 10:49:55 +0200

Kevin Diggs <[email-masked]> writes:

> Jeremy Kerr wrote:
>> Hi Kevin,
>>
>>
>>>         /*
>>>          * Turn r3 (range) into a rotate count for the selected
>>>range. * 0 -> 23, 1 -> 31
>>>          */
>>>         __asm__ __volatile__ (  "slwi %0,%0,3\n"
>>>                                 "addi %0,%0,23\n"
>>>                                 "rlwnm %0,%1,%0,30,31\n":
>>>                 "=r"(ret):
>>>                 "r"(config),"0"(range)
>>>         );
>>
>>
>> Wouldn't this be much simpler in plain C?
>>
> I just knew someone was gonna try to rain on my rlwnm'in fun parade!
> Wonder if the C code can be made to compile down to 3 instructions?

This will do:

unsigned int get_PLL_range(unsigned int range, unsigned int config)
{
  range = range * 8 + 23;
  return ((config << range) | (config >> (32 - range))) & 3;
}

The special pattern ((a << n) | (a >> (32 - n))) is recognized by gcc as
a rotate operation.

Andreas.

-- 
Andreas Schwab, SuSE Labs, [email-masked]
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."