Расширения SSE/AVX предоставляют следующие поразрядные логические операции:
andpd
: логическое умножение dest = dest and source
(128-разрядные операнды)
vandpd
: логическое умножение dest = source1 and source2
(128- или 256-разрядные операнды)
andnpd
: логическое умножение с отрицанием (NAND) dest = dest and ~source
(128-разрядные операнды)
vandnpd
: логическое умножение с отрицанием (NAND) dest = source1 and ~source2
(128- или 256-разрядные операнды)
orpd
: логическое сложение dest = dest | source
(128-разрядные операнды)
vorpd
: логическое сложение dest = source1 | source2
(128- или 256-разрядные операнды)
xorpd
: операция XOR dest = dest ^ source
(128-разрядные операнды)
vxorpd
: операция XOR dest = source1 ^ source2
(128- или 256-разрядные операнды)
Синтаксис инструкций:
andpd xmmdest, xmmsrc/mem128 vandpd xmmdest, xmmsrc1, xmmsrc2/mem128 vandpd ymmdest, ymmsrc1, ymmsrc2/mem256 andnpd xmmdest, xmmsrc/mem128 vandnpd xmmdest, xmmsrc1, xmmsrc2/mem128 vandnpd ymmdest, ymmsrc1, ymmsrc2/mem256 orpd xmmdest, xmmsrc/mem128 vorpd xmmdest, xmmsrc1, xmmsrc2/mem128 vorpd ymmdest, ymmsrc1, ymmsrc2/mem256 xorpd xmmdest, xmmsrc/mem128 vxorpd xmmdest, xmmsrc1, xmmsrc2/mem128 vxorpd ymmdest, ymmsrc1, ymmsrc2/mem256
Инструкции SSE (без префикса v) оставляют старшие биты в целевом регистре YMM без изменений. Инструкции AVX (с префиксом v), которые имеют 128-битные операнды, заполняют старшие 128 бит регистра YMM нулями. Если третий операнд является переменной, он должен быть выровнен по соответствующей границе (например, 16 байтов для значений mem128 и 32 байта для значений mem256). Невыполнение этого требования приведет к ошибке выравнивания памяти во время выполнения.
Пример применения:
.data nums0 dword 0, 1, 0, 1 nums1 dword 0, 1, 1, 0 .code main proc movaps xmm0, nums0 movaps xmm1, nums1 andpd xmm0, xmm1 ; XMM0 = 0, 1, 0, 0 ret main endp end
Здесь в регистры XMM0 и XMM1 загружаются соответственно векторы nums0 и nums1. Далее к элементам этих векторов применяется логическая операции AND, которая возвращает 1, если только обы разряда двух операндов равны 1. То есть мы получим следующие вычисления:
0, 1, 0, 1 * 0, 1, 1, 0 = 0, 1, 0, 0
В итоге в регистре XMM0 будет содержаться вектор 0, 1, 0, 0