Инструкции (v)pavgb и (v)pavgw вычисляют среднее значение двух соответствующих дорожек операндов:
pavgb xmmsrc/mem128, xmmdest vpavgb xmmsrc2/mem128, xmmsrc1, xmmdest vpavgb ymmsrc2/mem256, ymmsrc1, ymmdest pavgw xmmsrc/mem128, xmmdest vpavgw xmmsrc2/mem128, xmmsrc1, xmmdest vpavgw ymmsrc2/mem256, ymmsrc1, ymmdest
128-битные инструкции pavgb
и vpavgb
берут два байта из соответствующих 16 дорожек первого и второго операндах и вычисляют среднее этих двух чисел. Среднее
значение помещается во вторй операнд.
256-битный вариант инструкции vpavgb
вычисляет средние значения для 32 дорожек.
128-битные инструкции pavgw
и vpavgw
вычисляют 8 средних значений для каждой пары слов из 8 дорожек первого и второго операнда.
256-битный вариант инструкции vpavgw
вычисляет средние значения для 16 дорожек.
Если результат дробный, то он округляется.
Пример применения:
.globl main .data nums0: .long 3, 4, 6, 7 nums1: .long 2, 3, 4, 5 format_str: .asciz "%d, %d, %d, %d\n" .text main: subq $8, %rsp movaps nums0, %xmm0 movaps nums1, %xmm1 pavgw %xmm1, %xmm0 # XMM0 = (XMM0 + XMM1) / 2 # XMM0 = 3, 4, 5, 6 # выводим данные на консоль movd %xmm0, %esi psrldq $4, %xmm0 movd %xmm0, %edx psrldq $4, %xmm0 movd %xmm0, %ecx psrldq $4, %xmm0 movd %xmm0, %r8d movq $format_str, %rdi call printf addq $8, %rsp ret
Пример работы:
root@Eugene:~/asm# gcc -static hello.s -o hello root@Eugene:~/asm# ./hello 3, 4, 5, 6 root@Eugene:~/asm#
Расширения SSE4.1 добавили восемь инструкций для поиска минимума и максимума из двух соответствующих дорожек:
(v)pmaxsb
: выбирает максимальное однобайтовое число со знаком из соответствующих дорожек операндов.
(v)pmaxsw
: выбирает максимальное 16-битное число со знаком из соответствующих дорожек операндов.
(v)pmaxsd
: выбирает максимальное 32-битное число со знаком (sdword).
vpmaxsq
: выбирает максимальное 64-битное число со знаком.
(v)pmaxub
: выбирает максимальное беззнаковое 8-битное число из соответствующих дорожек операндов.
(v)pmaxuw
: выбирает максимальное беззнаковое 16-битное число.
(v)pmaxud
: выбирает максимальное беззнаковое 32-битное число.
vpmaxuq
: выбирает максимальное беззнаковое 64-битное число.
(v)pminsb
: выбирает минимальное однобайтовое число со знаком из соответствующих дорожек операндов.
(v)pminsw
: выбирает минимальное 16-битное число со знаком из соответствующих дорожек операндов.
(v)pminsd
: выбирает минимальное 32-битное число со знаком (sdword).
vpminsq
: выбирает минимальное 64-битное число со знаком.
(v)pminub
: выбирает минимальное беззнаковое 8-битное число из соответствующих дорожек операндов.
(v)pminuw
: выбирает минимальное беззнаковое 16-битное число.
(v)pminud
: выбирает минимальное беззнаковое 32-битное число.
vpminuq
: выбирает минимальное беззнаковое 64-битное число.
Общий синтаксис инструкций на примере pmaxuw
и vpmaxuw
(остальные инструкции имеют аналогичный синтаксис)
pmaxuw xmmsrc/mem128, xmmdest vpmaxuw xmmsrc2/mem128, xmmsrc1, xmmdest vpmaxuw ymmsrc2/mem256, ymmsrc1, ymmdest
Эти инструкции сканируют дорожки пары 128- или 256-битных операндов и копируют максимальное или минимальное значение из этой дорожки в ту же дорожку первого операнда. Пример нахожжения максимальных слов в дорожках:
.globl main .data nums0: .long 2, 3, 8, 9 nums1: .long 4, 5, 6, 7 format_str: .asciz "%d, %d, %d, %d\n" .text main: subq $8, %rsp movaps nums0, %xmm0 movaps nums1, %xmm1 pmaxud %xmm1, %xmm0 # XMM0 = (XMM0 + XMM1) / 2 # XMM0 = 4, 5, 8, 9 # выводим данные на консоль movd %xmm0, %esi psrldq $4, %xmm0 movd %xmm0, %edx psrldq $4, %xmm0 movd %xmm0, %ecx psrldq $4, %xmm0 movd %xmm0, %r8d movq $format_str, %rdi call printf addq $8, %rsp ret
Пример работы:
root@Eugene:~/asm# gcc -static hello.s -o hello root@Eugene:~/asm# ./hello 4, 5, 8, 9 root@Eugene:~/asm#
SSE/AVX предоставляют несколько инструкций для вычисления абсолютных значений целых чисел со знаком: (v)pabsb
(для байтов), (v)pabsw
(для слов) и
(v)pabsd
(для двойных слов). Их синтаксис:
pabsb xmmsrc/mem128, xmmdest vpabsb xmmsrc/mem128, xmmdest vpabsb ymmsrc/mem256, ymmdest pabsw xmmsrc/mem128, xmmdest vpabsw xmmsrc/mem128, xmmdest vpabsw ymmsrc/mem256, ymmdest pabsd xmmsrc/mem128, xmmdest vpabsd xmmsrc/mem128, xmmdest vpabsd ymmsrc/mem256, ymmdest
Инструкции pabsb, pabsw и pabsd не изменяют старшие 128 битов регистров YMM, а 128-битные версии инструкций vpabsb, vpabsw и vpabsd заполняют нулями старшие 128 битов регистров YMM.