Использование g++ 4.9.2, если я компилирую
bool int_dbl_com(const unsigned long long x, const double y)
{
return x <= y;
}
тогда выход ассемблера:
testq %rcx, %rcx
js .L2
pxor %xmm0, %xmm0
cvtsi2sdq %rcx, %xmm0
ucomisd %xmm0, %xmm1
setae %al
ret
Команда cvtsi2sdq
- это преобразование с подписью, а первая комбинация тестов и прыжков - проверить, есть ли %rcx < 0
. Если это так, переходим к L2, и этого я не понимаю:
.L2:
movq %rcx, %rax
andl $1, %ecx
pxor %xmm0, %xmm0
shrq %rax
orq %rcx, %rax
cvtsi2sdq %rax, %xmm0
addsd %xmm0, %xmm0
ucomisd %xmm0, %xmm1
setae %al
ret
Наилучшим образом, вы можете вдвое уменьшить %rcx
, преобразовать в double в %xmm0
, а затем добавить %xmm0
в себя, чтобы вернуть исходное значение (признав, конечно, что вы потеряли некоторую точность низкого порядка переход от 64-битного целого к 64-битовому поплавку).
Но это не то, что делает код: он, кажется, сохраняет бит младшего разряда %rcx
, а затем возвращает его обратно в результат. Зачем?? И зачем беспокоиться, когда эти бит младшего порядка будут потеряны в любом случае (или я ошибаюсь здесь)?
(Тот же алгоритм, по-видимому, используется независимо от оптимизации, я использовал -O3 здесь, чтобы было легче видеть.)