Скачиваний:
50
Добавлен:
15.09.2014
Размер:
815.62 Кб
Скачать

3.6. Дополнительные команды simd над целыми

Аналогично командам технологии MMX, новые SIMD-команды обработки целочисленных данных:

  • Выполняют SIMD-операции над несколькими целочисленными элементами данных, упакованными в 64-разрядные группы.

  • Загружают и хранят упакованные данные в 64-разрядных MMX-регистрах (отдельно от 128-разрядных XMM-регистров данных с плавающей запятой).

Мнемоника имен новых целочисленных SIMD-команд включает префикс и суффиксы, указывающие на характер выполняемой операции и тип используемых данных:

  • Префикс p указывает на то, что команда выполняет параллельные операции над несколькими элементами данных;

  • Суффиксы b,w,d и q указывают на используемый тип данных;

  • Суффиксы u или s указывают на использование данных со знаком или без знака соответственно.

Так, например, команда умножения pmulhuw работает с данными типа «упакованные 16-разрядные слова без знака».

Команды PAVGB/PAVGW (Average unsigned source sub-operands, without incurring a loss in precision) сложения беззнаковых элементов данных операнда-источника с беззнаковыми элементами данных регистра назначения. Потом результат сложения каждого элемента независимо сдвигается вправо на один бит. Старшие биты каждого элемента заполняются битами переноса суммы. Для предотвращения накопления ошибок округления, выполняется усреднение. Младший бит каждого окончательного сдвинутого результата устанавливается в 1, если два младших бита промежуточной не сдвинутой суммы были равны 1.

PAVGB:

mm1[7-0] = (mm1[7-0] + mm2/m64[7-0] + 1)>>1;

mm1[15-8] = (mm1[15-8] + mm2/m64[15-8] + 1)>>1;

mm1[23-16] = (mm1[23-16] + mm2/m64[23-16] + 1)>>1;

mm1[31-24] = (mm1[31-24] + mm2/m64[31-24] + 1)>>1;

mm1[39-32] = (mm1[39-32] + mm2/m64[39-32] + 1)>>1;

mm1[47-40] = (mm1[47-40] + mm2/m64[47-40] + 1)>>1;

mm1[55-48] = (mm1[55-48] + mm2/m64[55-48] + 1)>>1;

mm1[63-56] = (mm1[63-56] + mm2/m64[63-56] + 1)>>1;

PAVGW:

mm1[15-0] = (mm1[15-0] + mm2/m64[15-0] + 1)>>1;

mm1[31-16] = (mm1[31-16] + mm2/m64[31-16] + 1)>>1;

mm1[47-32] = (mm1[47-32] + mm2/m64[47-32] + 1)>>1;

mm1[63-48] = (mm1[63-48] + mm2/m64[63-48] + 1)>>1;

Команда PEXTRW (Extract 16-bit word from MMX register) копирует слово из регистра MMX определенного двумя младшими битами 8-разрядного непосредственного операнда в младшее слово 32-разрядного целочисленного регистра; все 16 старших разрядов выходного регистра обнуляются.

sel = imm8 & 0x3;

mm_temp = (mm >> (sel * 16)) & 0xFFFF;

r[15-0] = mm_temp[15-0];

r[31-16] = 0x0000;

Команда PINSRW (Insert 16-bit word into MMX register) копирует младшее 16‑разрядное слово из 32-разрядного целочисленного регистра (или 16 разрядов данных из памяти) в одно из слов MMX регистра, определенное значением двух младших разрядов 8-разрядного непосредственного операнда.

sel = imm8 & 0x3;

mask = (sel == 0) ? 0x000000000000FFFF:

(sel == 1) ? 0x00000000FFFF0000:

(sel == 2) ? 0x0000FFFF00000000:

0xFFFF000000000000;

mm = (mm & ~mask) | ((m16/r32[15-0] << (sel * 16)) & mask);

Команды PMAXUB/PMAXSW (Maximum of packed unsigned integer bytes or signed integer words) копирует максимум каждой пары упакованных элементов данных в регистр назначения.

PMAXSW:

mm1[15-0] = ( mm1[15-0] > mm2/m64[15-0] ) ? mm1[15-0] : mm2/m64[15-0];

mm1[31-16] = ( mm1[31-16] > mm2/m64[31-16] ) ? mm1[31-16]: mm2/m64[31-16];

mm1[47-32] = ( mm1[47-32] > mm2/m64[47-32] ) ? mm1[47-32]: mm2/m64[47-32];

mm1[63-48] = ( mm1[63-48] > mm2/m64[63-48] ) ? mm1[63-48]: mm2/m64[63-48];

PMAXUB:

mm1[7-0] = ( mm1[7-0] > mm2/m64[7-0] ) ? mm1[7-0] : mm2/m64[7-0];

mm1[15-8] = ( mm1[15-8] > mm2/m64[15-8] ) ? mm1[15-8] : mm2/m64[15-8];

mm1[23-16] = ( mm1[23-16] > mm2/m64[23-16] ) ? mm1[23-16]: mm2/m64[23-16];

mm1[31-24] = ( mm1[31-24] > mm2/m64[31-24] ) ? mm1[31-24]: mm2/m64[31-24];

mm1[39-32] = ( mm1[39-32] > mm2/m64[39-32] ) ? mm1[39-32]: mm2/m64[39-32];

mm1[47-40] = ( mm1[47-40] > mm2/m64[47-40] ) ? mm1[47-40]: mm2/m64[47-40];

mm1[55-48] = ( mm1[55-48] > mm2/m64[55-48] ) ? mm1[55-48]: mm2/m64[55-48];

mm1[63-56] = ( mm1[63-56] > mm2/m64[63-56] ) ? mm1[63-56]: mm2/m64[63-56];

Команды PMINUB/PMINSW (Minimum of packed unsigned integer bytes or signed integer words) копирует минимум каждой пары упакованных элементов данных в регистр назначения.

PMINSW:

mm1[15-0] = ( mm1[15-0] < mm2/m64[15-0] ) ? mm1[15-0] : mm2/m64[15-0];

mm1[31-16] = ( mm1[31-16] < mm2/m64[31-16] ) ? mm1[31-16]: mm2/m64[31-16];

mm1[47-32] = ( mm1[47-32] < mm2/m64[47-32] ) ? mm1[47-32]: mm2/m64[47-32];

mm1[63-48] = ( mm1[63-48] < mm2/m64[63-48] ) ? mm1[63-48]: mm2/m64[63-48];

PMINUB:

mm1[7-0] = ( mm1[7-0] < mm2/m64[7-0] ) ? mm1[7-0] : mm2/m64[7-0];

mm1[15-8] = ( mm1[15-8] < mm2/m64[15-8] ) ? mm1[15-8] : mm2/m64[15-8];

mm1[23-16] = ( mm1[23-16] < mm2/m64[23-16] ) ? mm1[23-16]: mm2/m64[23-16];

mm1[31-24] = ( mm1[31-24] < mm2/m64[31-24] ) ? mm1[31-24]: mm2/m64[31-24];

mm1[39-32] = ( mm1[39-32] < mm2/m64[39-32] ) ? mm1[39-32]: mm2/m64[39-32];

mm1[47-40] = ( mm1[47-40] < mm2/m64[47-40] ) ? mm1[47-40]: mm2/m64[47-40];

mm1[55-48] = ( mm1[55-48] < mm2/m64[55-48] ) ? mm1[55-48]: mm2/m64[55-48];

mm1[63-56] = ( mm1[63-56] < mm2/m64[63-56] ) ? mm1[63-56]: mm2/m64[63-56];

Команда PMOVMSKB (Move Byte Mask from MMX register) копирует старшие (знаковые) биты всех восьми упакованных байтов входного операнда - MMX регистра и формирует 8-разрядную маску в младших разрядах 32-разрядного целочисленного регистра. Все старшие 24 разряда выходного целочисленного регистра обнуляются.

r32[7] = mm[63];

r32[6] = mm[55];

r32[5] = mm[47];

r32[4] = mm[39];

r32[3] = mm[31];

r32[2] = mm[23];

r32[1] = mm[15];

r32[0] = mm[7];

r32[31-8] = 0x000000;

Команда PMULHUW (Unsigned high packed integer word multiply in MMX register) попарно перемножает четыре 16-разрядных слова без знака входного и выходного операндов (регистра MMX), что дает четыре 32-разрядных промежуточных произведения без знака. Старшие 16 разрядов произведений записываются в 16‑разрядные слова выходного операнда. Младшие 16 разрядов промежуточных произведений теряются.

mm1[15-0] = ( mm1[15-0] * mm2/m64[15-0] )[31-16];

mm1[31-16] = ( mm1[31-16] * mm2/m64[31-16] )[31-16];

mm1[47-32] = ( mm1[47-32] * mm2/m64[47-32] )[31-16];

mm1[63-48] = ( mm1[63-48] * mm2/m64[63-48] )[31-16];

Команда PSADBW (Sum of absolute differences) вычисляет абсолютную разность для каждой пары байтовых под-операндов регистра источника, и затем суммирует эти восемь разностей в один 16-битный результат.

temp0 = abs( mm1[7-0] - mm2/m64[7-0] );

temp1 = abs( mm1[15-8] - mm2/m64[15-8] );

temp2 = abs( mm1[23-16] - mm2/m64[23-16] );

temp3 = abs( mm1[31-24] - mm2/m64[31-24] );

temp4 = abs( mm1[39-32] - mm2/m64[39-32] );

temp5 = abs( mm1[47-40] - mm2/m64[47-40] );

temp6 = abs( mm1[55-48] - mm2/m64[55-48] );

temp7 = abs( mm1[63-56] - mm2/m64[63-56] );

mm1[15-0] = temp0 + temp1 + temp2 + temp3 + temp4 + temp5 + temp6 + temp7;

mm1[31-16] = 0x0000;

mm1[47-32] = 0x0000;

mm1[63-48] = 0x0000;

Команда PSHUFW (Shuffle packed integer word in MMX register) выбирает четыре 16-разрядных слова (не обязательно различных) из входного операнда и записывает их в определенном порядке в выходной операнд. Порядок записи слов задается 2‑разрядными полями 8-разрядного непосредственного операнда. Входной операнд может располагаться либо в MMX регистре, либо в памяти. Выходной операнд должен находиться в MMX-регистре.

mm1[15-0] = ( mm2/m64 >> (imm8[1-0] * 16) )[15-0];

mm1[31-16] = ( mm2/m64 >> (imm8[3-2] * 16) )[15-0];

mm1[47-32] = ( mm2/m64 >> (imm8[5-4] * 16) )[15-0];

mm1[63-48] = ( mm2/m64 >> (imm8[7-6] * 16) )[15-0];

Соседние файлы в папке Лекции