Математические инструкции SSE/AVX

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

Среднее значение

Инструкции (v)pavgb и (v)pavgw вычисляют среднее значение двух соответствующих дорожек операндов:

pavgb xmmdest, xmmsrc/mem128
vpavgb xmmdest, xmmsrc1, xmmsrc2/mem128
vpavgb ymmdest, ymmsrc1, ymmsrc2/mem256
pavgw xmmdest, xmmsrc/mem128
vpavgw xmmdest, xmmsrc1, xmmsrc2/mem128
vpavgw ymmdest, ymmsrc1, ymmsrc2/mem256

128-битные инструкции pavgb и vpavgb берут два байта из соответствующих 16 дорожек первого и второго операндах и вычисляют среднее этих двух чисел. Среднее значение помещается в первый операнд. 256-битный вариант инструкции vpavgb вычисляет средние значения для 32 дорожек.

128-битные инструкции pavgw и vpavgw вычисляют 8 средних значений для каждой пары слов из 8 дорожек первого и второго операнда. 256-битный вариант инструкции vpavgw вычисляет средние значения для 16 дорожек.

Если результат дробный, то он округляется.

Пример применения на Linux:

global main

extern printf

section .data
nums0 dd 3, 4, 6, 7 
nums1 dd 2, 3, 4, 5
format_str db "%d, %d, %d, %d", 10, 0

section .text
main: 
    sub rsp, 8

    movaps xmm0, [nums0]
    movaps xmm1, [nums1]
    pavgw xmm0, xmm1       ; XMM0 = (XMM0 + XMM1) / 2 
    ; XMM0 = 3, 4, 5, 6

    ; выводим данные на консоль
    movd esi, xmm0
    psrldq xmm0, 4
    movd edx, xmm0
    psrldq xmm0, 4
    movd ecx, xmm0
    psrldq xmm0, 4
    movd r8d, xmm0
    mov rdi, format_str
    call printf

    add rsp, 8
    ret

Пример работы:

root@Eugene:~/asm# nasm -f elf64 hello.asm -o hello.o
root@Eugene:~/asm# gcc -static  hello.o -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 xmmdest, xmmsrc/mem128
vpmaxuw xmmdest, xmmsrc1, xmmsrc2/mem128
vpmaxuw ymmdest, ymmsrc1, ymmsrc2/mem256

Эти инструкции сканируют дорожки пары 128- или 256-битных операндов и копируют максимальное или минимальное значение из этой дорожки в ту же дорожку первого операнда. Пример нахожжения максимальных слов в дорожках в программе на Linux:

global main

extern printf

section .data
nums0 dd 2, 3, 8, 9
nums1 dd 4, 5, 6, 7
format_str db "%d, %d, %d, %d", 10, 0

section .text
main: 
    sub rsp, 8

    movaps xmm0, [nums0]
    movaps xmm1, [nums1]
    pmaxud xmm0, xmm1       ; XMM0 = (XMM0 + XMM1) / 2 
    ; XMM0 = 4, 5, 8, 9

    ; выводим данные на консоль
    movd esi, xmm0
    psrldq xmm0, 4
    movd edx, xmm0
    psrldq xmm0, 4
    movd ecx, xmm0
    psrldq xmm0, 4
    movd r8d, xmm0
    mov rdi, format_str
    call printf

    add rsp, 8
    ret

Пример работы:

root@Eugene:~/asm# nasm -f elf64 hello.asm -o hello.o
root@Eugene:~/asm# gcc -static  hello.o -o hello
root@Eugene:~/asm# ./hello
4, 5, 8, 9
root@Eugene:~/asm#

Абсолютное значение

SSE/AVX предоставляют несколько инструкций для вычисления абсолютных значений целых чисел со знаком: (v)pabsb (для байтов), (v)pabsw (для слов) и (v)pabsd (для двойных слов). Их синтаксис:

pabsb xmmdest, xmmsrc/mem128
vpabsb xmmdest, xmmsrc/mem128
vpabsb ymmdest, ymmsrc/mem256

pabsw xmmdest, xmmsrc/mem128
vpabsw xmmdest, xmmsrc/mem128
vpabsw ymmdest, ymmsrc/mem256

pabsd xmmdest, xmmsrc/mem128
vpabsd xmmdest, xmmsrc/mem128
vpabsd ymmdest, ymmsrc/mem256

Инструкции pabsb, pabsw и pabsd не изменяют старшие 128 битов регистров YMM, а 128-битные версии инструкций vpabsb, vpabsw и vpabsd заполняют нулями старшие 128 битов регистров YMM.

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