有没有办法增加 xmm 寄存器中的值?

Is there a way to increase a value in a xmm register?

我想知道,有没有办法增加 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

简而言之,不,不是你想的那样。

在 SSE 下,所有原始的 XMM 寄存器都是浮点寄存器。浮点数没有自增运算

SSE2增加了一些整型寄存器,但还是没有增量。这些寄存器和添加的运算实际上是为高速算术运算而设计的,包括点积、四舍五入的精确积等。

递增运算是您期望应用于通用寄存器或累加器的东西。

您可能会发现 this set of slides 在总体概述和功能方面有些信息。

xmm regs 没有 inc 等价物,也没有 paddw 的立即操作数形式(因此也没有 add eax, 1 等价物)。

paddw (and other element sizes) are only available with xmm/m128 source operands. So if you want to increment one element of a vector, you need to load a constant from memory, .

例如增加 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.

如果构建常量需要多于两条指令,或者寄存器压力有问题,那么从内存中加载常量可能是个好主意。


如果你想构造一个常量来仅递增低 32 位元素,例如,你可以使用字节移位将其他元素归零:

; 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

如果您的尝试应该只是增加 xmm2 中的低 16 位元素,那么是的,这是一个愚蠢的尝试。 IDK 你正在做什么存储到 [rbx+8] 然后加载到 xmm1(将高 96 位归零)。

以下是如何以不那么笨的方式编写 xmm -> gp -> xmm 往返。 (与具有矢量常数的 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.

如果您想使用 16 位以外的元素,您可以使用 SSE4.1 pinsrb/d/q,或者使用 movd 和随机播放。


参见 Agner Fog's Optimize Assembly guide for more good tips on how to use SSE vectors. Also other links in the 标签 wiki。