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

3.2.4. Команды упакованного/скалярного нахождения минимума и максимума

Команды нахождения минимума и максимума производят попарное сравнение соответствующих элементов двух операндов и записывают минимальные или максимальные значения в выходной операнд. Входной операнд для этих команд может располагаться либо в XMM-регистре, либо в памяти. Выходной операнд должен обязательно находиться в XMM-регистре. Поддерживаются как параллельные, так и скалярные операции (MAXPS (Maximum packed, single-precision, floating-point), MAXSS, MINPS и MINSS).

MAXPS:

xmm1[31-0] = (xmm1[31-0] == NaN) ? xmm1[31-0]:

(xmm2[31-0] == NaN) ? xmm1[31-0]:

(xmm1[31-0] > xmm2/m128[31-0]) ? xmm1[31-0] : xmm2/m128[31-0]);

xmm1[63-32] = (xmm1[63-32] == NaN) ? xmm1[63-32]:

(xmm2[63-32] == NaN) ? xmm1[63-32]:

(xmm1[63-32] > xmm2/m128[63-32]) ? xmm1[63-32] : xmm2/m128[63-32]);

xmm1[95-64] = (xmm1[95-64] == NaN) ? xmm1[95-64]:

(xmm2[95-64] == NaN) ? xmm1[95-64]:

(xmm1[95-64] > xmm2/m128[95-64]) ? xmm1[95-64] : xmm2/m128[95-64]);

xmm1[127-96] = (xmm1[127-96] == NaN) ? xmm1[127-96]:

(xmm2[127-96] == NaN) ? xmm1[127-96]:

(xmm1[127-96]>xmm2/m128[127-96])?xmm1[127-96]: xmm2/m128[127-96]);

MAXSS:

xmm1[31-0] = (xmm1[31-0] == NaN) ? xmm1[31-0]:

(xmm2[31-0] == NaN) ? xmm1[31-0]:

(xmm1[31-0] > xmm2/m128[31-0]) ? xmm1[31-0] : xmm2/m128[31-0]);

xmm1[63-32] = xmm1[63-32];

xmm1[95-64] = xmm1[95-64];

xmm1[127-96] = xmm1[127-96];

MINPS:

xmm1[31-0] = (xmm1[31-0] == NaN) ? xmm1[31-0]:

(xmm2[31-0] == NaN) ? xmm1[31-0]:

(xmm1[31-0] < xmm2/m128[31-0]) ? xmm1[31-0] : xmm2/m128[31-0]);

xmm1[63-32] = (xmm1[63-32] == NaN) ? xmm1[63-32]:

(xmm2[63-32] == NaN) ? xmm1[63-32]:

(xmm1[63-32] < xmm2/m128[63-32]) ? xmm1[63-32] : xmm2/m128[63-32]);

xmm1[95-64] = (xmm1[95-64] == NaN) ? xmm1[95-64]:

(xmm2[95-64] == NaN) ? xmm1[95-64]:

(xmm1[95-64] < xmm2/m128[95-64]) ? xmm1[95-64] : xmm2/m128[95-64]);

xmm1[127-96] = (xmm1[127-96] == NaN) ? xmm1[127-96]:

(xmm2[127-96] == NaN) ? xmm1[127-96]:

(xmm1[127-96]< xmm2/m128[127-96])?xmm1[127-96]: xmm2/m128[127-96]);

MINSS:

xmm1[31-0] = (xmm1[31-0] == NaN) ? xmm1[31-0]:

(xmm2[31-0] == NaN) ? xmm1[31-0]:

(xmm1[31-0] < xmm2/m128[31-0]) ? xmm1[31-0] : xmm2/m128[31-0]);

xmm1[63-32] = xmm1[63-32];

xmm1[95-64] = xmm1[95-64];

xmm1[127-96] = xmm1[127-96];

3.3. Команды сравнения

Команды сравнения попарно сравнивают все четыре соответствующих FP‑элемента двух операндов (для скалярного варианта команд – только младшие элементы) и проверяют выполнение арифметического условия, специфичного для каждой команды. Если для сравниваемой пары условие выполняется, то в соответствующие 32 разряда выходного операнда записывается маска из всех единиц, в противном случае – маска из нулей. Получаемая в результате двоичная маска обычно используется при логических операциях с объектами. Входной операнд может располагаться либо в XMM регистре, либо в памяти. Выходным операндом должен быть XMM регистр (SIMD регистр).

Команды сравнения:

Команда CMPPS (Compare packed, single-precision, floating-point) сравнивает четыре пары упакованных чисел одинарной точности с плавающей точкой, используя непосредственный операнд как предикат, возвращает как результат в каждом поле SP все "1" (32-битовая маска) или все "0". Команда поддерживает набор условий (см. табл. 4), которые передаются ей в качестве третьего операнда.

switch (imm8)

{

case eq : op = eq; break;

case lt : op = lt; break;

case le : op = le; break;

case unord : op = unord; break;

case neq : op = neq; break;

case nlt : op = nlt; break;

case nle : op = nle; break;

case ord : op = ord; break;

default : raise(INVALID_OPCODE); break;

}

cmp0 = op(xmm1[31-0], xmm2/m128[31-0] );

cmp1 = op(xmm1[63-32], xmm2/m128[63-32] );

cmp2 = op(xmm1[95-64], xmm2/m128[95-64] );

cmp3 = op(xmm1[127-96], xmm2/m128[127-96]);

xmm1[31-0] = cmp0 ? 0xFFFFFFFF : 0x00000000;

xmm1[63-32] = cmp1 ? 0xFFFFFFFF : 0x00000000;

xmm1[95-64] = cmp2 ? 0xFFFFFFFF : 0x00000000;

xmm1[127-96] = cmp3 ? 0xFFFFFFFF : 0x00000000;

Команда CMPSS (Compare scalar single-precision, floating-point) сравнивает младшую пару упакованных чисел, используя непосредственный операнд как предикат (как и в CMPPS), возвращает как результат в младшем поле SP 32-битовую маску из всех "1" или всех "0".

switch (imm8)

{

case eq : op = eq; break;

case lt : op = lt; break;

case le : op = le; break;

case unord : op = unord; break;

case neq : op = neq; break;

case nlt : op = nlt; break;

case nle : op = nle; break;

case ord : op = ord; break;

default : raise(INVALID_OPCODE); break;

}

cmp0 = op(xmm1[31-0], xmm2/m32[31-0] );

xmm1[31-0] = cmp0 ? 0xFFFFFFFF : 0x00000000;

xmm1[63-32] = xmm2[63-32];

xmm1[95-64] = xmm2[95-64]

xmm1[127-96] =xmm2[127-96]

Эквивалентная форма

Фактическая форма

Тип сравнения

CMPEQ[PS,SS] xmm1,xmm2

CMPLT[PS,SS] xmm1,xmm2

CMPLE[PS,SS] xmm1,xmm2

CMPUNORD[PS,SS] xmm1,xmm2

CMPNEQ[PS,SS] xmm1,xmm2

CMPNLT[PS,SS] xmm1,xmm2

CMPNLE[PS,SS] xmm1,xmm2

CMPORD[PS,SS] xmm1,xmm2

CMP[PS,SS] xmm1,xmm2,0

CMP[PS,SS] xmm1,xmm2,1

CMP[PS,SS] xmm1,xmm2,2

CMP[PS,SS] xmm1,xmm2,3

CMP[PS,SS] xmm1,xmm2,4

CMP[PS,SS] xmm1,xmm2,5

CMP[PS,SS] xmm1,xmm2,6

CMP[PS,SS] xmm1,xmm2,7

равно

меньше

меньше или равно

неупорядочены

не равно

не меньше

не меньше или равно

упорядочены

Таблица 7. Две формы записи команд сравненияCMP[PS,SS].

Команда COMISS (Compare scalar single-precision, floating-point ordered and set EFLAGS) сравнивает младшую пару упакованных чисел, и устанавливает флаги ZF, PF, и CF в регистре флагов EFLAGS (флаги OF, SF, и AF сбрасываются).

switch (xmm1[31-0]<>xmm2/m32[31-0])

{

case UNORDERED : ZF,PF,CF = 111; break;

case GREATER_THAN : ZF,PF,CF = 000; break;

case LESS_THAN : ZF,PF,CF = 001; break;

case EQUAL : ZF,PF,CF = 100; break;

}

Команда UCOMISS (Unordered compare scalar single-precision, floating-point ordered and set EFLAGS) сравнивает младшую пару упакованных чисел, и устанавливает флаги ZF, PF, и CF в регистре флагов EFLAGS (флаги OF, SF, и AF сбрасываются).

switch (xmm1[31-0]<>xmm2/m32[31-0])

{

case UNORDERED : ZF,PF,CF = 111; break;

case GREATER_THAN : ZF,PF,CF = 000; break;

case LESS_THAN : ZF,PF,CF = 001; break;

case EQUAL : ZF,PF,CF = 100; break;

}

При этом COMISS реализует исключение типа #1, если хотя бы один из операндов не число (SnaN или QnaN), а UCOMISS – если элемент одного из операндов является SnaN.

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