http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45903
--- Comment #1 from Zdenek Sojka <zsojka at seznam dot cz> 2010-10-06 10:03:48
UTC ---
The first example should actually be:
f64:
mov al, DWORD PTR [esp+5]
add al, DWORD PTR [esp+13]
ret
This happens to other operators, not just plus:
uint8_t f64or(uint64_t a, uint64_t b)
{
return (a >> 8) | (b >> 8);
}
is compiled as:
f64or:
push ebx
mov ecx, DWORD PTR [esp+8]
mov ebx, DWORD PTR [esp+12]
mov eax, DWORD PTR [esp+16]
mov edx, DWORD PTR [esp+20]
shrd ecx, ebx, 8
pop ebx
shrd eax, edx, 8
or eax, ecx
ret
or when the shift is done after the operation:
uint8_t f64or2(uint64_t a, uint64_t b)
{
return (a | b) >> 8;
}
results in:
f64or2:
mov ecx, DWORD PTR [esp+12]
mov eax, DWORD PTR [esp+4]
mov edx, DWORD PTR [esp+8]
or eax, ecx
mov ecx, DWORD PTR [esp+16]
or edx, ecx
shrd eax, edx, 8
ret
When there is no shift, code is better:
uint8_t f64or3(uint64_t a, uint64_t b)
{
return a | b;
}
is compiled as
f64or3:
mov eax, DWORD PTR [esp+12]
or al, BYTE PTR [esp+4]
ret