For example with such function,
int fb(char a, char b, char c, char d) {
return (a + b) - (c + d);
}
gcc's assembly output is,
fb:
movsx esi, sil
movsx edi, dil
movsx ecx, cl
movsx edx, dl
add edi, esi
add edx, ecx
mov eax, edi
sub eax, edx
ret
Vaguely, I understand that the purpose of movsx is to remove the dependency from the previous value of the register, but honestly I still don't understand exactly what kind of dependency it is trying to remove. I mean, for example, whether or not there is movsx esi, sil, if some value is being written to esi, then any operation using esi will have to wait, if a value is being read from esi, any operation modifying the value of esi will have to wait, and if esi isn't being used by any operation, the code will continue to run. What difference does movsx make? I cannot say the compiler is doing wrong because movsx or movzx is (almost?) always produced by any compiler whenever loading values smaller than 32-bits.
Apart from my lack of understanding, gcc behaves differently with floats.
float ff(float a, float b, float c, float d) {
return (a + b) - (c + d);
}
is compiled to,
ff:
addss xmm0, xmm1
addss xmm2, xmm3
subss xmm0, xmm2
ret
If the same logic was applied, I believe the output should be something like,
ff:
movd xmm0, xmm0
movd xmm1, xmm1
movd xmm2, xmm2
movd xmm3, xmm3
addss xmm0, xmm1
addss xmm2, xmm3
subss xmm0, xmm2
ret
So I'm actually asking 2 questions.
- Why does
gccbehave differently withfloats? - What difference does
movsxmake?