Для выполнения арифметических действий над числами с плавающей точкой расширения SSE предоставляет ряд инструкций:
addss и addsd: сложение
subss и subsd: вычитание
mulss и mulsd: умножение
divss и divsd: деление
minss и minsd: вычисляют минимальное значение двух операндов, сохраняя минимальное значение в первом операнде.
maxss и maxsd: вычисляют максимальное значение двух операндов, сохраняя минимальное значение в первом операнде.
sqrtss и sqrtsd: вычисляют квадратный корень второго операнда и сохраняют результат в первый операнд
rcpss и rcpsd: вычисляют обратное значение второго операнда, сохраняя результат в первый операнд
rsqrtss и rsqrtsd: вычисляют обратное значение квадратного корня второго операнда, сохраняя результат в первый операнд
Инструкции, которые оканчиваются на ss, предназначены для 32-разрядных чисел с плавающей точкой (ss - сокращение от "scalar single"). Инструкции, которые оканчиваются на sd, предназначены для 64-разрядных чисел с плавающей точкой (sd - сокращение от "scalar double"). Общий синтаксис инструкций:
addss xmmn, xmmn addss mem32, xmmn addsd xmmn, xmmn addsd mem64, xmmn subss xmmn, xmmn subss mem32, xmmn subsd xmmn, xmmn subsd mem64, xmmn mulss xmmn, xmmn mulss mem32, xmmn mulsd xmmn, xmmn mulsd mem64, xmmn divss xmmn, xmmn divss mem32, xmmn divsd xmmn, xmmn divsd mem64, xmmn minss xmmn, xmmn minss mem32, xmmn minsd xmmn, xmmn minsd mem64, xmmn maxss xmmn, xmmn maxss mem32, xmmn maxsd xmmn, xmmn maxsd mem64, xmmn sqrtss xmmn, xmmn sqrtss mem32, xmmn sqrtsd xmmn, xmmn sqrtsd mem64, xmmn rcpss xmmn, xmmn rcpss mem32, xmmn rsqrtss xmmn, xmmn rsqrtss mem32, xmmn
Второй операнд всегда должен быть регистром XMM. Например, сложим два числа:
.globl _start .data num1: .double 3.4 num2: .double 6.6 .text _start: movsd num1, %xmm0 # помещаем в xmm0 число num1 movsd num2, %xmm1 # помещаем в xmm1 число num2 addsd %xmm1, %xmm0 # xmm0 = xmm0 + xmm1 cvtsd2si %xmm0, %rdi # из xmm0 преобразуем в целое число и помещаем в rdi movq $60, %rax syscall
В данном случае складываем два числа типа .double - num1 и num2, которые предварительно загружаются в регистры xmm0 и xmm1. После сложения результат помещается в регистр xmm0, а затем конвертируется в целое число и помещается в регистр rdi. Таким образом, в регистре rdi в итоге окажется число 10.