bug in arch/ppc/kernel/misc.S: __ashrdi3?
Gabriel Paubert
paubert at iram.es
Mon Jul 18 22:14:04 EST 2005
On Sun, Jul 17, 2005 at 04:24:57AM +1000, Benjamin Herrenschmidt wrote:
> On Sat, 2005-07-16 at 20:02 +0200, Andreas Schwab wrote:
> > Benjamin Herrenschmidt <benh at kernel.crashing.org> writes:
> >
> > > On Fri, 2005-07-15 at 18:01 +0200, Frank van Maarseveen wrote:
> > >> I don't really grok the code but an operand seems to be missing and the
> > >> assembler makes something out of it I don't trust:
> > >>
> > >> _GLOBAL(__ashrdi3)
> > >> ...
> > >> rlwinm r8,r7,0,32 # t3 = (count < 32) ? 32 : 0
> > >
> > > This is equivalent to r8 = r7 & 32. It will definitely not do what the
> > > comment says though. If (count < 64), however, it will do something
> > > like r8 = (r7 < 32) ? 0 : 32. Paul, maybe we should dbl check what's
> > > going in there ?
> >
> > r7 is count + 32, and ((count + 32) & 32) is equivalent to the expression
> > above if count < 64.
>
> Ok, with some context it makes more sense :)
Well, I wrote this code, to be fair I actually took most of these
code sequences from the multi precision shift appendix found in
all good PPC instruction set books. The exception is __ashrdi3
which I modified slightly to eliminate a conditional branch.
I tested it fairly exhaustively before submitting it. So the
comments might be wrong (and they will definitely look wrong
without the correct context), but the code very likely gives
the correct result. After all it has been used for quite some
time now without any complaint.
Now obviously the function only works for shift counts below
64, since the C language specification clearly states that
the result is undefined for shift counts equal or larger than
the bit size of the operand (but I felt against rebooting the
machine for an operand outside the allowed range, although
a simple "twlgti count,63" might do it).
Maybe this last point should be clearly stated in a comment.
Regards,
Gabriel
More information about the Linuxppc-dev
mailing list