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