2016-07-10 5 views
2

Мне было интересно, есть ли способ увеличить значение в регистре xmm или вы можете переместить значение только в один?Есть ли способ увеличить значение в регистре xmm?

То, что я имею в виду, вы можете сделать это:

inc eax 

или как это:

inc [ebp+7F00F000] 

есть способ сделать то же самое с XMM?

Я пытался что-то напоминает, но ... это не работает

inc [rbx+08] 
    movss xmm1,[rbx+08] 

Я даже пытался что-то действительно глупо, но это также не работает

push edx 
pextrw edx,xmm2,0 
add edx,1 
mov [rbx+08],edx 
movss xmm1,[rbx+08] 
pop edx 
+0

Вы хотите увеличить все целочисленные значения в регистре xmm или только один? – galinette

+1

Возможный дубликат [Добавить постоянное значение в регистр xmm в x86] (http://stackoverflow.com/questions/14088228/add-a-constant-value-to-a-xmm-register-in-x86) –

+0

только один – Gecko64

ответ

1

В Короче, нет, не так, как ты думаешь.

Под SSE все исходные регистры XMM были регистром с плавающей запятой. Для с плавающей запятой нет операции увеличения.

SSE2 добавил несколько регистров целочисленного типа, но по-прежнему нет приращения. Эти регистры и дополнительные операции были действительно предназначены для высокоскоростных арифметических операций, включая такие вещи, как точечные продукты, точные продукты с округлением и т. Д.

Операция приращения - это то, что вы ожидаете найти применительно к общему регистру или аккумулятор.

Вы можете найти this set of slides несколько информативный с точки зрения общего обзора и функции.

+0

спасибо за ответ – Gecko64

+2

SSE2 использует одни и те же регистры XMM, он просто добавил инструкции, которые работают с целыми типами данных, включая целочисленное сложение/вычитание для размеров элементов b/w/d/q. Совершенно нормально делать векторные целые добавления в реестре XMM. Вы даже можете использовать их для [создания генератора последовательности Фибоначчи] (http://stackoverflow.com/questions/32659715/assembly-language-x86-how-to-create-a-loop-to-calculate-fibonacci-sequence/ 32661389 # 32661389), если хотите. –

+0

Питер, SSE2 на современных AMD/Intel использует те же регистры XMM для int и для fp, когда блокируют блоки int и fp, а в AMD они имеют отдельные PRF: http://hothardware.com/articleimages/Item1552/BobcatDetail1.jpg – osgx

7

Нет эквивалента inc для xmm regs, и нет формы немедленного операнда paddw (так что нет никакого эквивалента add eax, 1).

paddw (and other element sizes) доступны только с операндами источника xmm/m128. Поэтому, если вы хотите увеличить один элемент вектора, вам нужно загрузить константу из памяти, or generate it on the fly.

например. самый дешевый способ для увеличения всех элементов XMM0 является:

; outside the loop 
pcmpeqw xmm1,xmm1  # xmm1 = all-ones = -1 

; inside the loop 
psubw  xmm0, xmm1 ; xmm0 -= -1 (in each element). i.e. xmm0++ 

Или

paddw  xmm0, [ones] ; where ones is a static constant. 

Возможно только хорошая идея, чтобы загрузить константу из памяти, если она занимает больше, чем, может быть, две инструкции, чтобы построить константу, или если давление в регистре является проблемой.


Если вы хотите построить постоянное приращение только низкий элемент 32bit, например, вы можете использовать байтовый сдвиг к нулю другие элементы:

; hoisted out of the loop 
pcmpeqw xmm1,xmm1  # xmm1 = all-ones = -1 
psrldq  xmm1, 12  # xmm1 = [ 0 0 0 -1 ] 


; in the loop 
psubd  xmm0, xmm1 

Если ваша попытка должен был увеличивать только малый 16-битный элемент в xmm2, тогда да, это была глупая попытка.IDK, что вы делаете, сохраняете в [rbx+8], а затем загружаете в xmm1 (обнуление высоких 96 бит).

Ниже приведено описание того, как написать xmm -> gp -> xmm round trip менее тупым способом. (Все еще ужасно по сравнению с paddw с векторной константой).

# don't push/pop. Instead, pick a register you can clobber without saving/restoring 
movd edx, xmm2  # this is the cheapest way to get the low 16. It doesn't matter that we also get the element 1 as garbage in the high half of edx 
inc  edx    # we only care about dx, but this is still the most efficient instruction 
pinsrw xmm2, edx, 0 # normally you'd just use movd again, but we actually want to merge with the old contents. 

Если вы хотите работать с другими, чем 16bit элементов, вы либо использовать SSE4.1 pinsrb/d/q, или вы хотите использовать movd и перетасовки.


См Agner Fog's Optimize Assembly руководства для более хороших советов о том, как использовать векторы SSE. Также другие ссылки в теге .