For this piece of C code:
uint64_t roundUp(uint64_t value, uint32_t blockSize)
{
return (value + blockSize - 1) & ~(blockSize - 1);
}
gcc 4.6 -O3 generated the following assembly:
roundUp(unsigned long, unsigned int):
.LFB0:
.cfi_startproc
movl %esi, %edx
movl %esi, %esi
leaq -1(%rdi,%rsi), %rax
negl %edx
andl %edx, %eax
ret
.cfi_endproc
Could anyone tell me why would it want to do this?
movl %esi, %esi
That clears the upper 32 bits. When you write to a 32 bit register in x86-64, the upper 32 bits are cleared automatically. Since
esicontains a 32 bit parameter, the upper 32 bits could contain any value, so they need to be cleared beforersican be used.