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

Reply via email to