Лучший способ загрузить 64-битное целое число в регистр SSE2 с двойной точностью?

Каков наилучший/самый быстрый способ загрузки 64-разрядного целочисленного значения в регистр xmm SSE2 в 32-битном режиме?

В 64-битном режиме может использоваться cvtsi2sd, но в 32-битном режиме он поддерживает только 32-разрядные целые числа.

До сих пор я не нашел много чего:

  • используйте fild, fstp для стека, затем movsd в xmm register
  • загрузите 32-разрядную часть с высоким значением, умножьте на 2 ^ 32, добавьте 32-разрядный минимум

Первое решение медленное, второе решение может привести к прецизионным потерям (edit:), и в любом случае он медленный, так как низкий 32-разрядный бит должен быть преобразован как без знака...)

Любой лучший подход?

Ответы

Ответ 1

Второй вариант можно сделать для работы, хотя он немного громоздкий. Я предполагаю, что ваш 64-разрядный номер изначально находится в edx: eax.

cvtsi2sd xmm0, edx              // high part * 2**-32
mulsd    xmm0, [2**32 from mem] // high part
movsd    xmm2, [2**52 from mem]
movd     xmm1, eax
orpd     xmm1, xmm2             // (double)(2*52 + low part as unsigned)
subsd    xmm1, xmm2             // (double)(low part as unsigned)
addsd    xmm0, xmm1             // (double)(high part + low part as unsigned)

Все операции, за исключением, возможно, окончательного, точны, поэтому это правильно округлено. Следует отметить, что это преобразование создает -0.0, когда входной сигнал 0, а параметр mxcsr установлен в круг-минус-бесконечность. Это нужно было бы решить, если бы оно использовалось в библиотеке времени выполнения для компилятора с целью обеспечения соответствия IEEE-754, но это не является проблемой для большинства видов использования.