Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Asm: Общие вопросы > Модуль числа в XMM регистре


Автор: Russel 9.8.2006, 17:24
Добрый День, У меня в XMM регистре находятся 8 целых чисел со знаком по 16 бит, как мне получить модули этих чисел? SSE2...

Автор: sgi1981 10.8.2006, 03:51
Думал я думал...
И придумал последовательность из пяти инструкций XMM-расширения.
Придумать из меньшего количества инструкций не удалось.

Код

;я допустил, что изначально у вас исходный вектор находится в xmm0 и xmm1 свободен
 movdqa xmm1,xmm0;
 psraw xmm1,15;
 pxor xmm0,xmm1;
 psrlw xmm1,15;
 paddw xmm0,xmm1;


Объясняю.
В xmm1 копруем вектор из xmm0.

Если соответствующий элемент вектора xmm1 отрицательный - то при арифметическом сдвиге на 15 разрядов в двухбайтном слове элемента вектора все разряды окажутся равными 1, в противном случае они все будут 0.

После выполнения команды исключающего ИЛИ (pxor) в отрицательных элементах исходного вектора все биты изменят значения на противоположные, а в положительных элементах нет, так как отрицательный элемент дал в xmm1 значение ffffh, а положительный - значение 0000h. В результате этого в xmm0 на месте каждого отрицательного элемента вектора получится значение на единицу меньшее модуля бывшего отрицательного значения.

Значит необходимо сложить с элементами вектора xmm0, на месте которых были отрицательные числа, значение 1, а с остальными - значение 0.Эти значения мы получим из элементов вектора xmm1 путем логического сдвига элементов на 15 разрядов вправо.

Складываем полученный вектор xmm1 с xmm0 и получим в регистре xmm0 то что требуется - модуль элементов.

Автор: Mayk 11.8.2006, 08:33
Цитата(sgi1981 @  10.8.2006,  07:51 Найти цитируемый пост)


Значит необходимо сложить с элементами вектора xmm0, на месте которых были отрицательные числа, значение 1, а с остальными - значение 0.Эти значения мы получим из элементов вектора xmm1 путем логического сдвига элементов на 15 разрядов вправо.

Если мы будем вычитать а не складывать, то мы сэкономим целую команду.  -(-1) = +1

Цитата(sgi1981 @  10.8.2006,  07:51 Найти цитируемый пост)
 psrlw xmm1,15;
 paddw xmm0,xmm1;

заменить на psubw xmm0, xmm1.
Примерно так делают компиляторы когда хотят получить модуль числа.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)