Расширения SSE для чисел с плавающей точкой

Последнее обновление: 02.07.2023

В дополнение к FPU Intel предоставляет еще один механизм для работы с числами с плавающей точкой - расширения SSE или Streaming SIMD Extensions, которые призваны преодолеть недостатки стековой архитектуры FPU. Для вычислений SSE определяет 16 регистров XMM (от XMM0 до XMM15).

Набор инструкций SSE поддерживает два типа данных с плавающей точкой: 32-битные значения одинарной точности и 64-битные значения двойной точности. 80-битные значения расширенной точности не поддерживаются.

Регистр управления

Для управления операциями SSE с плавающей точкой в SSE предназначен 32-битный регистр состояния и управления SSE MXCSR. Первые 16 бит имеют определенное значение:

  • 0 (IE): Флаг исключения недопустимой операции. Устанавливается, если была попытка выполнить недопустимую операцию

  • 1 (DE): Флаг исключения денормализации. Устанавливается, если результат операции - денормализованное значение

  • 2 (ZE): Флаг нулевого исключения. Устанавливается, если была предпринята попытка деления на 0.

  • 3 (OE): Флаг переполнения. Устанавливается, если было переполнение.

  • 4 (UE): Флаг потери значимости (underflow). Устанавливается, если была потеря значимости

  • 5 (PE): Флаг потери точности. Устанавливается, если была потеря точности.

  • 6 (DAZ): Денормализованные значения равны 0. Если установлено, денормализованные значения обрабатываются как 0.

  • 7 (IM): Неверная маска операции. Если установлено, исключения недопустимой операции игнорируются

  • 8 (DM): Денормализованная маска. Если установлено, исключения денормализации игнорируются

  • 9 (ZM): Маска деления на ноль. Если установлено, исключения деления на ноль игнорируются

  • 10 (OM): Маска переполнения. Если установлено, исключения переполнения игнорируются

  • 11 (UM): Маска потери значимости. Если установлено, исключения потери значимости игнорируются

  • 12 (PM): Маска точности. Если установлено, исключения точности игнорируются

  • 13-14: Управление округлением. может принимать ряд значений:

    • 00: округление до ближайшего

    • 01: округление до -бесконечности

    • 10: округление до +бесконечности

    • 11: округление до 0 (усечение)

  • 15 (FTZ): Сброс до нуля. Когда установлено, все условия потери значимости устанавливают регистр в 0

Остальне биты 16-32 зарезервированы и в настоящее время не имеют значения.

Доступ к регистру SSE MXCSR осуществляется с помощью следующих двух инструкций:

ldmxcsr mem32
stmxcsr mem32

Инструкция ldmxcsr загружает регистр MXCSR из 32-битной переменной. Инструкция stmxcsr сохраняет текущее содержимое регистра MXCSR в 32-битную переменную. Как правило, данный регистр применяется для установки режима округления.

Помещение данных в регистр

Для перемещения данных между регистрами XMM и переменными для чисел с плавающей точкой одинарной точности применяется инструкция movss, а для чисел с плавающей точкой двойной точности - инструкция movsd:

movss xmmn, mem32
movss mem32, xmmn
movsd xmmn, mem64
movsd mem64, xmmn

Для максимальной производительности переменные, используемые в инструкции movss, должны располагаться выравненны в памяти по двойному слову (4 бита), а операнды инструкции movsd — по адресу памяти, выровненному по четверному слову.

В дополнение SSE предоставляет инструкции movd и movq, которые позволяют перемещать данные между регистрами XMM и 32- и 64-битными регистрами общего назначения:

movd reg32, xmmn
movd xmmn, reg32
movq reg64, xmmn
movq xmmn, reg64

Стоит отметить, что эти команды не преобразуют значения с плавающей точкой в целые числа.

Преобразования SSE

SSE предоставляет ряд инструкций для преобразования чисел с плавающей точкой в целые числа и обратно:

  • cvtsd2si: преобразует число с плавающей точкой двойной точности в 32- или 64-битное целое число. Использует текущий режим округления в MXCSR. Результат сохраняется в 32- или 64-битном регистре общего назначения.

    cvtsd2si reg32/64, xmmn/mem64
  • cvtsd2ss: преобразует число с плавающей точкой двойной точности (в регистре XMM или переменной) в число с плавающей точкой одинарной точности и оставляет результат в первом операнде - регистре XMM. Использует текущий режим округления в MXCSR.

    cvtsd2ss xmmn, xmmn/mem64
  • cvtsi2sd: преобразует 32- или 64-разрядное целое число в целочисленном регистре или переменной в число с плавающей точкой двойной точности, оставляя результат в регистре XMM.

    cvtsi2sd xmmn, reg32/64/mem32/64
  • cvtsi2ss: преобразует 32- или 64-разрядное целое число в целочисленном регистре или переменной в число с плавающей точкой одинарной точности, оставляя результат в регистре XMM.

    cvtsi2ss xmmn, reg32/64/mem32/64
  • cvtss2sd: преобразует значение с плавающей точкой одинарной точности в регистре XMM или переменной в значение двойной точности, оставляя результат в регистре XMM в первом операнде.

    cvtss2sd xmmn, xmmn/mem32
  • cvtss2si: преобразует значение с плавающей точкой одинарной точности в регистре XMM или переменной в целое число и оставляет результат в 32- или 64-битном регистре общего назначения. Использует текущий режим округления в MXCSR.

    cvtss2si reg32/64, xmmn/mem32
  • cvttsd2si: преобразует значение с плавающей точкой двойной точности в 32- или 64-битное целое число. Преобразование выполняется с использованием усечения (не использует биты управления округлением в MXCSR). Результат сохраняется в 32- или 64-битном регистре общего назначения.

    cvttsd2si reg32/64, xmmn/mem64
  • cvttss2si: преобразует значение с плавающей точкой одинарной точности в 32- или 64-битное целое число. Преобразование выполняется с использованием усечения (не использует биты управления округлением в MXCSR). Результат сохраняется в 32- или 64-битном регистре общего назначения.

    cvttss2si reg32/64, xmmn/mem32

Пример преобразования:

.data
    double1 real8 3.4
.code
main proc        
    movsd xmm0, double1     ; помещаем в xmm0 число double1
    cvtsd2si rax, xmm0      ; из xmm0 преобразуем в целое число и помещаем в rax
    ret
main endp
end

В данном случае число 3.4, которое хранится в XMM0, преобразуется в целочисленное значение. И мы получим в регистре RAX число 3.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850