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

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

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

Инструкции (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.

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