shifts on 64bit ints
Franz Sirl
Franz.Sirl-kernel at lauterbach.com
Fri Aug 4 09:54:53 EST 2000
At 01:02 04.08.00, David Edelsohn wrote:
> First, I would suggest that you use a printf format like "%08x"
>for better legibility.
>
> Second, I tried your example with gcc-2.95.2 on PowerPC AIX
>gcc-2.95.2 on PowrePC Linux, and a recent development snapshot of GCC with
>various optimization levels (you did not specify what options you used to
>compile the testcase) and I consistently saw the following output:
>
>Mask 29 is 0x0000000020000000 - 0xffffffffdfffffff
>Mask 30 is 0x0000000040000000 - 0xffffffffbfffffff
>Mask 31 is 0x0000000080000000 - 0xffffffff7fffffff
>Mask 32 is 0x0000000100000000 - 0xfffffffeffffffff
>Mask 33 is 0x0000000200000000 - 0xfffffffdffffffff
>Mask 34 is 0x0000000400000000 - 0xfffffffbffffffff
>
> You appear to have a problem, but it is local to your system
>(could be toolchain or C library as well).
Oh no!! It's even worse! The kernel implementation of ashldi3, ashrdi3 and
lshrdi3 seems broken, see this code in arch/ppc/kernel/misc.S:
/*
* Extended precision shifts
*
* R3/R4 has 64 bit value
* R5 has shift count
* result in R3/R4
*
* ashrdi3: XXXYYY/ZZZAAA -> SSSXXX/YYYZZZ
* ashldi3: XXXYYY/ZZZAAA -> YYYZZZ/AAA000
* lshrdi3: XXXYYY/ZZZAAA -> 000XXX/YYYZZZ
*/
_GLOBAL(__ashrdi3)
li r6,32
sub r6,r6,r5
slw r7,r3,r6 /* isolate YYY */
srw r4,r4,r5 /* isolate ZZZ */
or r4,r4,r7 /* YYYZZZ */
sraw r3,r3,r5 /* SSSXXX */
blr
_GLOBAL(__ashldi3)
li r6,32
sub r6,r6,r5
srw r7,r4,r6 /* isolate ZZZ */
slw r4,r4,r5 /* AAA000 */
slw r3,r3,r5 /* YYY--- */
or r3,r3,r7 /* YYYZZZ */
blr
_GLOBAL(__lshrdi3)
li r6,32
sub r6,r6,r5
slw r7,r3,r6 /* isolate YYY */
srw r4,r4,r5 /* isolate ZZZ */
or r4,r4,r7 /* YYYZZZ */
srw r3,r3,r5 /* 000XXX */
blr
I don't see how these can handle shift's >=32...
Somebody should fix that...
Franz.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-dev
mailing list