Re: inline assembly r0 SOS

2008-08-06 Thread Andreas Schwab
Kevin Diggs [EMAIL PROTECTED] 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 PROTECTED]
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.
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: inline assembly r0 SOS

2008-08-06 Thread Segher Boessenkool

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.


It's only valid for 1 = n = 31 though, so for input range 0 or 1.  
(*)

If that's the whole range needed, much simpler code is possible...


Segher

(*) or 0x or 0xfffe, but somehow I doubt that was intended.

___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


inline assembly r0 SOS

2008-08-05 Thread Kevin Diggs

Hi,

If I have:

inline unsigned int get_PLL_range(unsigned int range, unsigned int
config)
{
unsigned int ret;

/*
 * 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)
);

return ret;
}

in a header and the resultant code generated is:

.L58:
li 0,1   # ratio,
mr 29,0  # ret, ratio
#APP
slwi 29,29,3 # ret
addi 29,29,21# ret
rlwnm 29,28,29,27,31 # ret, ret

slwi 0,0,3   # ret
addi 0,0,23  # ret
rlwnm 0,28,0,30,31   # ret, ret

#NO_APP

thats bad right? Because the addi 0, 0, 23 will not work as expected 
because of the special property of r0. FYI:  The first three lines 
after the #APP are from a similar function get_PLL_ratio().


Is there a way to blacklist r0?

kevin
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: inline assembly r0 SOS

2008-08-05 Thread Benjamin Herrenschmidt
On Tue, 2008-08-05 at 17:20 -0700, Kevin Diggs wrote:
 Hi,
 

 thats bad right? Because the addi 0, 0, 23 will not work as expected 
 because of the special property of r0. FYI:  The first three lines 
 after the #APP are from a similar function get_PLL_ratio().
 
   Is there a way to blacklist r0?

Yes. Use b instead of r in the constraints to force the compiler
to avoid r0 when assigning a register.

Cheers,
Ben.


___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: inline assembly r0 SOS

2008-08-05 Thread Jeremy Kerr
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?

However, if you really do need to do this in inline asm, you can use 
the b modifier rather than r to avoid using r0.

Cheers,


Jeremy
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: inline assembly r0 SOS

2008-08-05 Thread Kevin Diggs

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?


However, if you really do need to do this in inline asm, you can use 
the b modifier rather than r to avoid using r0.



Oh cool! Thanks! You to Ben!


Cheers,


Jeremy



kevin
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev