Re: Shifting: what's going on?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I expect to get a 1 in the s-th bit of a, and zeroes in all other
bits. I don't know why you say that's an arithmetic overflow, if
unsigned long long is 64 bits long and it has a 63-th bit (the last
one).

Anyway, Rupert Wood comment works, thanks a lot.

FaQ

2007/3/29, Andrew Haley <aph@xxxxxxxxxx>:
Facundo Ciccioli writes:
 > Hi. What follows applies to gcc (GCC) 3.4.2 (mingw-special), platform
 > x86-32bits.
 >
 > This code:
 >
 > int main() {
 >     unsigned long long a= 1;
 >     unsigned s= 63;
 >
 >     a= (a << s);
 >
 >     return 0;
 > }
 > generates this assembler (removing preamble and prologue stuff):
 >
 >     movl    $1, -8(%ebp)
 >     movl    $0, -4(%ebp)
 >     movl    $63, -12(%ebp)
 >     movl    -12(%ebp), %ecx
 >     movl    -8(%ebp), %eax
 >     movl    -4(%ebp), %edx
 >     shldl   %cl,%eax, %edx
 >     sall    %cl, %eax
 >     testb   $32, %cl
 >     je  L2
 >     movl    %eax, %edx
 >     movl    $0, %eax
 > L2:
 >     movl    %eax, -8(%ebp)
 >     movl    %edx, -4(%ebp)
 >
 > This is fine, and works as I expect.
 > However, this code:
 >
 > int main() {
 >     unsigned long long a;
 >     unsigned s= 63;
 >
 >     a= (1 << s);
 >
 >     return 0;
 > }
 > generates this assembler:
 >
 >     movl    $63, -12(%ebp)
 >     movl    -12(%ebp), %ecx
 >     movl    $1, %eax
 >     sall    %cl, %eax
 >     cltd
 >     movl    %eax, -8(%ebp)
 >     movl    %edx, -4(%ebp)
 > which is... wrong. Not only the results aren't what they should, but
 > looking a little harder, the assembler generated doesn't seem to make
 > sense. What's with the CLTD instruction there? If I change s (the
 > shifted amount) to be 63 (31 is equivalent, because only 5 bits of %cl
 > are used) then the result are a bunch of 1's because the sign of %eax
 > goes all over %edx. And that's only one problem. If s is between 62
 > and 32, the 1 appears in %eax instead of being in %edx, where it
 > should.
 >
 > This is obviusly not urgent, since the first code is perfectly
 > acceptable and applicable to what I am doing, but I just got curious.

This is an arithmetic overflow, and is explicitly undefined.  One
result is as good as any other.  What do you expect the code to do?

Andrew.

--
Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE, UK
Registered in England and Wales No. 3798903


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux