SSE2指令集

1移动指令:

1.       Movaps
movaps XMM,XMM/m128 movaps XMM/128,XMM
把源存储器内容值送入目的寄存器,当有m128时,必须对齐内存16字节,也就是内存地址低4位为0.

2.       Movups
movups XMM,XMM/m128 movaps XMM/128,XMM
把源存储器内容值送入目的寄存器,但不必对齐内存16字节

3.       Movlps
movlps XMM,m64
把源存储器64位内容送入目的寄存器低64位,高64位不变,内存变量不必对齐内存16字节

4.       Movhps
movhps XMM,m64
把源存储器64位内容送入目的寄存器高64位,低64位不变,内存变量不必对齐内存16字节.

5.       Movhlps
movhlps XMM,XMM
把源寄存器高64位送入目的寄存器低64位,高64位不变.

6.       Movlhps
movlhps XMM,XMM
把源寄存器低64位送入目的寄存器高64位,低64位不变.

7.       movss
movss XMM,m32/XMM
原操作数为m32时:dest[31-00] <== m32      dest[127-32] <== 0
原操作数为XMM时: dest[31-00] <== src[31-00] dest[127-32]不变

8.       movmskpd
movmskpd r32,XMM
取64位操作数符号位
r32[0] <== XMM[63] r32[1] <== XMM[127] r32[31-2] <== 0

9.       movmskps
movmskps r32,XMM
取32位操作数符号位
r32[0] <== XMM[31] r32[1] <== XMM[63] r32[2] <== XMM[95] r32[3] <== XMM[127] r32[31-4] <== 0

10.   pmovmskb
pmovmskb r32,XMM
取16位操作数符号位 具体操作同前
r[0] <== XMM[7]   r[1] <== XMM[15]   r[2] <== XMM[23]   r[3] <== XMM[31]
r[4] <== XMM[39]   r[5] <== XMM[47]   r[6] <== XMM[55]   r[7] <== XMM[63]
r[8] <== XMM[71]   r[9] <== XMM[79]   r[10] <== XMM[87]   r[11] <== XMM[95]
r[12] <== XMM[103] r[13] <== XMM[111]  r[14] <== XMM[119]  r[15] <== XMM[127]  r[31-16] <== 0

11.   movntps
movntps m128,XMM
m128 <== XMM 直接把XMM中的值送入m128,不经过cache,必须对齐16字节.

12.   Movntpd
movntpd m128,XMM
m128 <== XMM 直接把XMM中的值送入m128,不经过cache,必须对齐16字节.

13.   Movnti
movnti m32,r32
m32 <== r32 把32寄存器的值送入m32,不经过cache.

14.   Movapd
movapd XMM,XMM/m128 movapd XMM/m128,XMM
把源存储器内容值送入目的寄存器,当有m128时,必须对齐内存16字节

15.   Movupd
movupd XMM,XMM/m128 movapd XMM/m128,XMM
把源存储器内容值送入目的寄存器,但不必对齐内存16字节.
我感觉这两条指令同movaps 和 movups 指令一样,不过又不确定.

16.   Movlpd
movlpd XMM,m64 movlpd m64,XMM
把源存储器64位内容送入目的寄存器低64位,高64位不变,内存变量不必对齐内存16字节

17.   Movhpd
movhpd XMM,m64 movhpd m64,XMM
把源存储器64位内容送入目的寄存器高64位,低64位不变,内存变量不必对齐内存16字节.

18.   Movdqa
movdqa XMM,XMM/m128 movdqa XMM/m128,XMM
把源存储器内容值送入目的寄存器,当有m128时,必须对齐内存16字节.

19.   Movdqu
movdqu XMM,XMM/m128 movdqu XMM/m128,XMM
把源存储器内容值送入目的寄存器,但不必对齐内存16字节.

20.   movq2dq
movq2dq XMM,MM
把源寄存器内容送入目的寄存器的低64位,高64位清零.

21.   movdq2q
movdq2q MM,XMM
把源寄存器低64位内容送入目的寄存器.

22.   Movd
movd XMM,r32/m32 movd MM,r32/m32
把源存储器32位内容送入目的寄存器的低32位,高96位清零.
movd r32/m32,XMM movd r32/m32,MM
把源寄存器的低32位内容送入目的存储器32位.

23.   Movq
movq XMM,XMM/m64 movq MM,MM/m64
把源存储器低64位内容送入目的寄存器的低64位,高64位清零.
movq m64,XMM
把源寄存器的低64位内容送入目的存储器.

2 加法操作

1.       addps
addps XMM,XMM/m128
源存储器内容按双字对齐,共4个单精度浮点数与目的寄存器相加,结果送入目的寄存器,内存变量必须对齐内存16字节

2.       adds
addss XMM,XMM/m32
源存储器的低32位1个单精度浮点数与目的寄存器的低32位1个单精度浮点数相加,结果送入目的寄存器的低32位高96位不变,内存变量不必对齐内存16字节

3.       addpd
addpd XMM,XMM/m128
源存储器内容按四字对齐,共两个双精度浮点数与目的寄存器相加,结果送入目的寄存器,内存变量必须对齐内存16字节.

4.       addsd
addsd XMM,XMM/m64
源存储器的低64位1个双精度浮点数与目的寄存器的低64位1个双精度浮点数相加,结果送入目的寄存器的低64位,高64位不变,内存变量不必对齐内存16字节

5.       paddd
paddd XMM,XMM/m128
把源存储器与目的寄存器按双字对齐无符号整数普通相加,结果送入目的寄存器,内存变量必须对齐内存16字节.

6.       Paddq
paddq XMM,XMM/m128
把源存储器与目的寄存器按四字对齐无符号整数普通相加,结果送入目的寄存器,内存变量必须对齐内存16字节.

7.       Paddq
paddq MM,MM/m64
把源存储器与目的寄存器四字无符号整数普通相加,结果送入目的寄存器.

8.       Pmaddwd
pmaddwd XMM,XMM/m128
把源存储器与目的寄存器分4组进行向量点乘(有符号补码操作),内存变量必须对齐内存16字节..
高64位 | 低64位
目的寄存器: a0 | a1 | a2 | a3 | a4 | a5 | a6 | a7
源存储器: b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7
目的寄存器结果: a0*b0+a1*b1 | a2*b2+a3*b3 | a4*b4+a5*b5 | a6*b6+a7*b7

9.       Paddsb
paddsb XMM,XMM/m128 paddsb MM,MM/m64
源存储器与目的寄存器按字节对齐有符号补码饱和相加,内存变量必须对齐内存16字节.

10.   paddsw 
paddsw XMM,XMM/m128
源存储器与目的寄存器按字对齐有符号补码饱和相加,内存变量必须对齐内存16字节.

11.   paddusb
paddusb XMM,XMM/m128
源存储器与目的寄存器按字节对齐无符号饱和相加,内存变量必须对齐内存16字节.

12.   Paddusw
paddusw XMM,XMM/m128
源存储器与目的寄存器按字对齐无符号饱和相加,内存变量必须对齐内存16字节.

13.   Paddb
paddb XMM,XMM/m128
源存储器与目的寄存器按字节对齐无符号普通相加,内存变量必须对齐内存16字节.

14.   Paddw
paddw XMM,XMM/m128
源存储器与目的寄存器按字对齐无符号普通相加,内存变量必须对齐内存16字节.

15.   Paddd
paddd XMM,XMM/m128
源存储器与目的寄存器按双字对齐无符号普通相加,内存变量必须对齐内存16字节.

16.   Paddq
paddq XMM,XMM/m128
源存储器与目的寄存器按四字对齐无符号普通相加,内存变量必须对齐内存16字节.

17.    

3 减法操作

1.       subps
subps XMM,XMM/m128
源存储器内容按双字对齐,共4个单精度浮点数与目的寄存器相减(目的减去源),结果送入目的寄存器, 内存变量必须对齐内存16字节.

2.       Subss
subss XMM,XMM/m32
源存储器的低32位1个单精度浮点数与目的寄存器的低32位1个单精度浮点数相减(目的减去源), 结果送入目的寄存器的低32位,高96位不变,内存变量不必对齐内存16字节

3.       Subpd
subpd XMM,XMM/m128
把目的寄存器内容按四字对齐,两个双精度浮点数,减去源存储器两个双精度浮点数, 结果送入目的寄存器,内存变量必须对齐内存16字节.

4.       subsd 
subsd XMM,XMM/m128
把目的寄存器的低64位1个双精度浮点数,减去源存储器低64位1个双精度浮点数,结果送入目的寄存器的低64位,高64位不变,内存变量不必对齐内存16字节

5.       Psubd
psubd XMM,XMM/m128
把目的寄存器与源存储器按双字对齐无符号整数普通相减,结果送入目的寄存器, 内存变量必须对齐内存16字节.(目的减去源)

6.       Psubq
psubq XMM,XMM/m128
把目的寄存器与源存储器按四字对齐无符号整数普通相减,结果送入目的寄存器, 内存变量必须对齐内存16字节.(目的减去源)

7.       Psubq
psubq MM,MM/m64
把目的寄存器与源存储器四字无符号整数普通相减,结果送入目的寄存器.(目的减去源)

8.       psubsb 
psubsb XMM,XMM/m128
源存储器与目的寄存器按字节对齐有符号补码饱和相减(目的减去源),内存变量必须对齐内存16字节.

9.       Psubsw
psubsw XMM,XMM/m128
源存储器与目的寄存器按字对齐有符号补码饱和相减(目的减去源),内存变量必须对齐内存16字节.

10.   Psubusb
psubusb XMM,XMM/m128
源存储器与目的寄存器按字节对齐无符号饱和相减(目的减去源),内存变量必须对齐内存16字节.

11.   Psubusw
psubusw XMM,XMM/m128
源存储器与目的寄存器按字对齐无符号饱和相减(目的减去源),内存变量必须对齐内存16字节.

12.   psubb 
psubb XMM,XMM/m128
源存储器与目的寄存器按字节对齐无符号普通相减(目的减去源),内存变量必须对齐内存16字节.

13.   Psubw
psubw XMM,XMM/m128
源存储器与目的寄存器按字对齐无符号普通相减(目的减去源),内存变量必须对齐内存16字节.

14.   Psubd
psubd XMM,XMM/m128
源存储器与目的寄存器按双字对齐无符号普通相减(目的减去源),内存变量必须对齐内存16字节.

15.   Psubq
psubq XMM,XMM/m128
源存储器与目的寄存器按四字对齐无符号普通相减(目的减去源),内存变量必须对齐内存16字节.

16.    

4 比较操作

1.       Maxps
maxps XMM,XMM/m128
源存储器4个单精度浮点数与目的寄存器4个单精度浮点数比较,较大数放入对应目的寄存器,内存变量必须对齐内存16字节.

2.       Maxss
maxss XMM,XMM/m32
源存储器低32位1个单精度浮点数与目的寄存器低32位1个单精度浮点数比较,较大数放入目的寄存器低32位,高96位不变内存变量不必对齐内存16字节

3.       Minps
minps XMM,XMM/m128
源存储器4个单精度浮点数与目的寄存器4个单精度浮点数比较,较小数放入对应目的寄存器,内存变量必须对齐内存16字节.

4.       minss
minss XMM,XMM/m32
源存储器低32位1个单精度浮点数与目的寄存器低32位1个单精度浮点数比较,较小数放入目的寄存器低32位,高96位不变内存变量不必对齐内存16字节

5.       cmpps
cmpps XMM0,XMM1,imm8 imm8是立即数范围是0~7
根据imm8的值进行4对单精度浮点数的比较,符合imm8的就置目的寄存器对应的32位全1,否则全0
当imm8 = 0时,目的寄存器等于原寄存器数时,置目的寄存器对应的32位全1,否则全0
imm8 = 1 时,目的寄存器小于原寄存器数时,置目的寄存器对应的32位全1,否则全0
imm8 = 2 时,目的寄存器小于等于原寄存器数时,置目的寄存器对应的32位全1,否则全0
imm8 = 4 时,目的寄存器不等于原寄存器数时,置目的寄存器对应的32位全1,否则全0
imm8 = 5 时,目的寄存器大于等于原寄存器数时,置目的寄存器对应的32位全1,否则全0
imm8 = 6 时,目的寄存器大于原寄存器数时,置目的寄存器对应的32位全1,否则全0

6.       pcmpeqb 
pcmpeqb XMM,XMM/m128
目的寄存器与源存储器按字节比较,如果对应字节相等,就置目的寄存器对应字节为0ffh,否则为00h内存变量必须对齐内存16字节.

7.       Pcmpeqw
pcmpeqw XMM,XMM/m128
目的寄存器与源存储器按字比较,如果对应字相等,就置目的寄存器对应字为0ffffh,否则为0000h, 内存变量必须对齐内存16字节

8.       Pcmpeqd
pcmpeqd XMM,XMM/m128
目的寄存器与源存储器按双字比较,如果对应双字相等,就置目的寄存器对应双字为0ffffffffh,否则为00000000h内存变量必须对齐内存16字节

9.       Pcmpgtb
pcmpgtb XMM,XMM/m128
目的寄存器与源存储器按字节(有符号补码)比较,如果目的寄存器对应字节大于源存储器,就置目的寄存器对应字节为0ffh, 否则为00h,内存变量必须对齐内存16字节

10.   Pcmpgtw
pcmpgtw XMM,XMM/m128
目的寄存器与源存储器按字(有符号补码)比较,如果目的寄存器对应字大于源存储器,就置目的寄存器对应字为0ffffh, 否则为0000h,内存变量必须对齐内存16字节.

11.   Pcmpgtd
pcmpgtd XMM,XMM/m128
目的寄存器与源存储器按双字(有符号补码)比较,如果目的寄存器对应双字大于源存储器, 就置目的寄存器对应双字为0ffffffffh,否则为00000000h,内存变量必须对齐内存16字节.

5 计算操作

1.       rcpps 
rcpps XMM,XMM/m128
源存储器4个单精度浮点数的倒数放入对应目的寄存器,内存变量必须对齐内存16字节
注:比如2.0E0的倒数为1÷2.0E0 = 5.0E-1, 这操作只有12bit的精度

2.       rcpss 
rcpss XMM,XMM/32
源存储器低32位1个单精度浮点数的倒数放入目的寄存器低32位,高96位不变

3.       rsqrtps
rsqrtps XMM,XMM/m128
源存储器4个单精度浮点数的开方的倒数放入对应目的寄存器,内存变量必须对齐内存16字节. 比如2.0E0的开方的倒数为1÷√2.0E0 ≈ 7.0711E-1, 这操作只有12bit的精度.

4.       Rsqrtss
rsqrtss XMM,XMM/32
源存储器低32位1个单精度浮点数的开方的倒数放入目的寄存器低32位,高96位不变,内存变量不必对齐内存16字节.

5.    Pavgb
pavgb MM,MM/m64 pavgb XMM,XMM/m128
把源存储器与目的寄存器按字节无符号整数相加,再除以2,结果四舍五入为整数放入目的寄存器, 源存储器为m128时,内存变量必须对齐内存16字节. 注:此运算不会产生溢出.

6.    Pavgw
pavgw MM,MM/m64 pavgw XMM,XMM/m128
把源存储器与目的寄存器按字无符号整数相加,再除以2,结果四舍五入为整数放入目的寄存器, 源存储器为m128时,内存变量必须对齐内存16字节.

7.       Sqrtpd
sqrtpd XMM,XMM/m128
源存储器两个双精度浮点数的开方放入对应目的寄存器,内存变量必须对齐内存16字节.

8.       Sqrtsd
sqrtsd XMM,XMM/m128
源存储器低64位1个双精度浮点数的开方放入目的寄存器低64位,高64位不变,内存变量不必对齐内存16字节

6 乘法操作

1.       Mulps
mulps XMM,XMM/m128
源存储器内容按双字对齐,共4个单精度浮点数与目的寄存器相乘,结果送入目的寄存器,内存变量必须对齐内存16字节.

2.       Mulss
mulss XMM,XMM/32
源存储器的低32位1个单精度浮点数与目的寄存器的低32位1个单精度浮点数相乘,结果送入目的寄存器的低32位,高96位不变,内存变量不必对齐内存16字节

3.       Mulpd
mulpd XMM,XMM/m128 
源存储器内容按四字对齐,共两个双精度浮点数与目的寄存器相乘,结果送入目的寄存器,内存变量必须对齐内存16字节

4.       Mulsd
mulsd XMM,XMM/m128
源存储器的低64位1个双精度浮点数与目的寄存器的低64位1个双精度浮点数相乘,结果送入目的寄存器的低64位,高64位不变,内存变量不必对齐内存16字节

5.       Pmuludq
pmuludq XMM,XMM/m128
把源存储器与目的寄存器的低32位无符号整数相乘,结果变为64位,送入目的寄存器低64位, 把源存储器与目的寄存器的高64位的低32位无符号整数相乘,结果变为64位,送入目的寄存器高64位内存变量必须对齐内存16字节.
高64位 | 低64位
目的寄存器: a0 | a1 | a2 | a3
源存储器: b0 | b1 | b2 | b3
目的寄存器结果: b1*a1 | b3*a3

6.       Pmuludq
pmuludq MM,MM/m64
把源存储器与目的寄存器的低32位无符号整数相乘,结果变为64位,送入目的寄存器.

7.       pmulhw 
pmulhw XMM,XMM/m128
源存储器与目的寄存器按字对齐有符号补码饱和相乘,取结果的高16位放入目的寄存器对应字中. 内存变量必须对齐内存16字节

8.       pmullw
pmullw XMM,XMM/m128
源存储器与目的寄存器按字对齐有符号补码饱和相乘,取结果的低16位放入目的寄存器对应字中. 内存变量必须对齐内存16字节.

9.        

7 除法操作

1.    Divps
divps XMM,XMM/m128
目的寄存器共4个单精度浮点数除以源存储器4个单精度浮点数,结果送入目的寄存器,内存变量必须对齐内存16字节.

2.    Divss
divss XMM,XMM/32
目的寄存器低32位1个单精度浮点数除以源存储器低32位1个单精度浮点数,结果送入目的寄存器的低32位, 高96位不变,内存变量不必对齐内存16字节

3.    Divpd
divpd XMM,XMM/m128
目的寄存器共两个双精度浮点数除以源存储器两个双精度浮点数,结果送入目的寄存器,内存变量必须对齐内存16字节

4.    Divsd
divsd XMM,XMM/m128
目的寄存器低64位1个双精度浮点数除以源存储器低64位1个双精度浮点数,结果送入目的寄存器的低64位, 高64位不变,内存变量不必对齐内存16字节.

8 位操作

1.       Andps
andps XMM,XMM/m128
源存储器128个二进制位'与'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.

2.       Orps
orps XMM,XMM/m128
源存储器128个二进制位'或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.

3.       Xorps
xorps XMM,XMM/m128
源存储器128个二进制位'异或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.

4.    Unpckhps
unpckhps XMM,XMM/m128
源存储器与目的寄存器高64位按双字交错排列,结果送入目的寄存器,内存变量必须对齐内存16字节.
高64位 | 低64位 
目的寄存器: a0 | a1 | a2 | a3 
源存储器:  b0 | b1 | b2 | b3 
目的寄存器结果: b0 | a0 | b1 | a1

5.    Unpcklps
 unpcklps XMM,XMM/m128
源存储器与目的寄存器低64位按双字交错排列,结果送入目的寄存器,内存变量必须对齐内存16字节
高64位 | 低64位
目的寄存器: a0 | a1 | a2 | a3 
源存储器:  b0 | b1 | b2 | b3 
目的寄存器结果: b2 | a2 | b3 | a3

6.    Pextrw
pextrw r32,MM,imm8 pextrw r32,XMM,imm8 imm8为8位立即数(无符号)
从源寄存器中选第imm8(0~3 或 0~7)个字送入目的寄存器的低16位,高16位清零.
注:imm8范围为 0~255,当源寄存器为'MM'时,有效值= imm8 mod 4,当目的寄存器为'XMM'时,有效值= imm8 mod 8

7.    Pinsrw
pinsrw MM,r32/m32,imm8 pinsrw XMM,r32/m32,imm8
把源存储器的低16位内容送入目的寄存器第imm8(0~3 或 0~7)个字,其余字不变
注:imm8范围为 0~255,当目的寄存器为'MM'时,有效值= imm8 mod 4,当目的寄存器为'XMM'时,有效值= imm8 mod 8

8.    Pmaxsw
pmaxsw MM,MM/m64 pmaxsw XMM,XMM/m128
把源存储器与目的寄存器按字有符号(补码)整数比较,大数放入目的寄存器对应字, 源存储器为m128时,内存变量必须对齐内存16字节

9.    Pmaxub
 pmaxub MM,MM/m64 pmaxsw XMM,XMM/m128
把源存储器与目的寄存器按字节无符号整数比较,大数放入目的寄存器对应字节, 源存储器为m128时,内存变量必须对齐内存16字节.

10. pminsw
pminsw MM,MM/m64 pmaxsw XMM,XMM/m128
把源存储器与目的寄存器按字有符号(补码)整数比较,较小数放入目的寄存器对应字, 源存储器为m128时,内存变量必须对齐内存16字节.

11. Pminub
pminub MM,MM/m64 pmaxsw XMM,XMM/m128
把源存储器与目的寄存器按字节无符号整数比较,较小数放入目的寄存器对应字节, 源存储器为m128时,内存变量必须对齐内存16字节

12. Maxpd
maxpd XMM,XMM/m128
源存储器两个双精度浮点数与目的寄存器两个双精度浮点数比较,较大数放入对应目的寄存器,内存变量必须对齐内存16字节.

13. Maxsd
maxsd XMM,XMM/m128
源存储器低64位1个双精度浮点数与目的寄存器低64位1个双精度浮点数比较,较大数放入目的寄存器低64位,高64位不变内存变量不必对齐内存16字节.

14. Minpd
minpd XMM,XMM/m128
源存储器两个双精度浮点数与目的寄存器两个双精度浮点数比较,较小数放入对应目的寄存器,内存变量必须对齐内存16字节.

15. Minsd
minsd XMM,XMM/m128
源存储器低64位1个双精度浮点数与目的寄存器低64位1个双精度浮点数比较,较小数放入目的寄存器低64位,高64位不变内存变量不必对齐内存16字节.

16. Andpd
andpd XMM,XMM/m128
源存储器128个二进制位'与'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.

17. Andnpd
andnpd XMM,XMM/m128
目的寄存器128个二进制位先取'非',再'与'源存储器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节

18. Orpd
orpd XMM,XMM/m128
源存储器128个二进制位'或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.

19. Xorpd
xorpd XMM,XMM/m128
源存储器128个二进制位'异或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.

20. Pslldq
pslldq XMM,imm8
把目的寄存器128位按imm8(立即数)指定字节数逻辑左移,移出的字节丢失.
imm8 == 1时,代表左移8位,imm8 == 2时,代表左移16位.

21. Psrldq
psrldq XMM,imm8
把目的寄存器128位按imm8(立即数)指定字节数逻辑右移,移出的字节丢失.
imm8 == 1时,代表右移8位,imm8 == 2时,代表右移16位.

22. Psllw
psllw XMM,XMM/m128 psllw XMM,imm8
把目的寄存器按字由源存储器(或imm8 立即数)指定位数逻辑左移,移出的位丢失. 低字移出的位不会移入高字,内存变量必须对齐内存16字节.

23. Psrlw
psrlw XMM,XMM/m128 psrlw XMM,imm8
把目的寄存器按字由源存储器(或imm8 立即数)指定位数逻辑右移,移出的位丢失.
高字移出的位不会移入低字,内存变量必须对齐内存16字节.

24. Pslld
pslld XMM,XMM/m128 pslld XMM,XMM imm8
把目的寄存器按双字由源存储器(或imm8 立即数)指定位数逻辑左移,移出的位丢失. 低双字移出的位不会移入高双字,内存变量必须对齐内存16字节.

25. Psrld
psrld XMM,XMM/m128 psrld XMM,imm8
把目的寄存器按双字由源存储器(或imm8 立即数)指定位数逻辑右移,移出的位丢失.
高双字移出的位不会移入低双字,内存变量必须对齐内存16字节.
pand 
pand XMM,XMM/m128
源存储器128个二进制位'与'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节. 我发现与andpd功能差不多,就不知其它特性是否一样

26. Pandn
pandn XMM,XMM/m128
目的寄存器128个二进制位先取'非',再'与'源存储器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节

27. Por
por XMM,XMM/m128
源存储器128个二进制位'或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.

28. Pxor
pxor XMM,XMM/m128
源存储器128个二进制位'异或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.

29. packuswb 
packuswb XMM,XMM/m128 packuswb MM,MM/m64
把目的寄存器按字有符号数压缩为字节无符号数放入目的寄存器低64位
把源寄存器按字有符号数压缩为字节无符号数放入目的寄存器高64位
压缩时负数变为00h,大于255的正数变为0ffh,内存变量必须对齐内存16字节.
高64位 | 低64位
目的寄存器: a0 | a1 | a2 | a3 | a4 | a5 | a6 | a7
源寄存器: b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7
目的寄存器压缩结果: b0|b1| b2| b3| b4|b5| b6|b7| a0|a1| a2|a3| a4|a5| a6| a7

30. packsswb 
packsswb XMM,XMM/m128 packsswb MM,MM/m64
把目的寄存器按字有符号数压缩为字节有符号数放入目的寄存器低64位
把源寄存器按字有符号数压缩为字节有符号数放入目的寄存器高64位
压缩时小于-128负数变为80h,大于127的正数变为7fh,内存变量必须对齐内存16字节.
高64位 | 低64位
目的寄存器: a0 | a1 | a2 | a3 | a4 | a5 | a6 | a7
源寄存器: b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7
目的寄存器压缩结果: b0|b1| b2| b3| b4|b5| b6|b7| a0|a1| a2|a3| a4|a5| a6| a7

31. packssdw
packssdw XMM,XMM/m128
把目的寄存器按双字有符号数压缩为字有符号数放入目的寄存器低64位
把源寄存器按双字有符号数压缩为字有符号数放入目的寄存器高64位
压缩时小于-32768负数变为8000h,大于32767的正数变为7fffh,内存变量必须对齐内存16字节.
高64位 | 低64位
目的寄存器: a0 | a1 | a2 | a3
源寄存器: b0 | b1 | b2 | b3
目的寄存器压缩结果: b0 | b1 | b2 | b3 | a0 | a1 | a2 | a3

32. punpckldq
punpckldq XMM,XMM/m128
把源存储器与目的寄存器低64位按双字交错排列,内存变量必须对齐内存16字节.
高64位 | 低64位
目的寄存器: a0 | a1 | a2 | a3
源寄存器: b0 | b1 | b2 | b3
目的寄存器排列结果: b2 | a2 | b3 | a3

33. punpckhdq 
把源存储器与目的寄存器高64位按双字交错排列,内存变量必须对齐内存16字节.
高64位 | 低64位
目的寄存器: a0 | a1 | a2 | a3
源寄存器: b0 | b1 | b2 | b3
目的寄存器排列结果: b0 | a0 | b1 | a1

34. punpcklwd
把源存储器与目的寄存器低64位按字交错排列,内存变量必须对齐内存16字节.
高64位 | 低64位
目的寄存器: a0 | a1 | a2 | a3 | a4 | a5 | a6 | a7
源寄存器: b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7
目的寄存器排列结果: b4 | a4 | b5 | a5 | b6 | a6 | b7 | a7

35. punpckhwd 
punpckhwd XMM,XMM/m128
把源存储器与目的寄存器高64位按字交错排列,内存变量必须对齐内存16字节.
高64位 | 低64位
目的寄存器: a0 | a1 | a2 | a3 | a4 | a5 | a6 | a7
源寄存器: b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7
目的寄存器排列结果: b0 | a0 | b1 | a1 | b2 | a2 | b3 | a3

36. punpcklbw
punpcklbw XMM,XMM/m128
把源存储器与目的寄存器低64位按字节交错排列,内存变量必须对齐内存16字节.
高64位 | 低64位
目的寄存器: a0|a1| a2| a3| a4|a5| a6|a7| a8|a9| aA|aB| aC|aD| aE| aF
源寄存器: b0|b1| b2| b3| b4|b5| b6|b7| b8|b9| bA|bB| bC|bD| bE| bF
目的寄存器排列结果: b8|a8| b9| a9| bA|aA| bB|aB| bC|aC| bD|aD| bE|aE| bF| aF

37. punpckhbw
把源存储器与目的寄存器高64位按字节交错排列,内存变量必须对齐内存16字节.
高64位 | 低64位
目的寄存器: a0|a1| a2| a3| a4|a5| a6|a7| a8|a9| aA|aB| aC|aD| aE| aF
源寄存器: b0|b1| b2| b3| b4|b5| b6|b7| b8|b9| bA|bB| bC|bD| bE| bF
目的寄存器排列结果: b0|a0| b1| a1| b2|a2| b3|a3| b4|a4| b5|a5| b6|a6| b7| a7

38. shufps
shufps XMM,XMM/m128,imm8
把源存储器与目的寄存器按双字划分,由imm8(立即数)八个二进制位(00~11,00^11,00~11,00~11)指定排列, 内存变量必须对齐内存16字节.目的寄存器高64位放源存储器被指定数,目的寄存器低64位放目的寄存器被指定数. '( )'中的都是二进制数
目的寄存器: a(11) | a(10) | a(01) | a(00)
源寄存器: b(11) | b(10) | b(01) | b(00)
目的寄存器排列结果: b(00~11) | b(00~11) | a(00~11) | a(00~11)
目的寄存器压缩结果'( )'中的值由imm8对应的两位二进制位指定.
例: ( 11 ) ( 10 ) ( 01 ) ( 00 ) ( 11 ) ( 10 ) ( 01 ) ( 00 )
当XMM0 = 090a0b0c 0d0e0f11 01020304 05060708 h,XMM1 = 0aabbccdd eeff1234 22334455 66778899 h, imm8 ══> (XMM1 10) (XMM1 01) (XMM0 11) (XMM0 00)
执行shufps XMM0,XMM1,10 01 11 00 b(二进制),则XMM0 = 0eeff1234 22334455 090a0b0c 05060708 h

39. shufpd
shufpd XMM,XMM/m128,imm8(0~255) imm8(操作值) = imm8(输入值) mod 4
把源存储器与目的寄存器按四字划分,由imm8(立即数)4个二进制位(0~1,0^1,0~1,0~1)指定排列, 内存变量必须对齐内存16字节.目的寄存器高64位放源存储器被指定数,目的寄存器低64位放目的寄存器被指定数.
当XMM0 = 1111111122222222 3333333344444444 h
XMM1 = 5555555566666666 aaaaaaaacccccccc h,执行shufpd XMM0,XMM1,101001 1 0 b
则XMM0 = 5555555566666666 3333333344444444 h

40. pshuflw
pshuflw XMM,XMM/m128,imm8(0~255)
先把源存储器的高64位内容送入目的寄存器的高64位,然后用imm8将源存储器的低64位4个字选入目的寄存器的低64位,内存变量必须对齐内存16字节.
源寄存器低64位: b(11) | b(10) | b(01) | b(00)
目的寄存器低64位排列结果: b(00~11) | b(00~11) | b(00~11) | b(00~11)
当XMM0 = 1111111122222222 3333 4444 5555 6666 h
XMM1 = 5555555566666666 7777 8888 9999 cccc h,执行pshuflw XMM0,XMM1,10 10 01 10 b
则XMM0 = 5555555566666666 8888 8888 9999 8888 h

41. pshufhw
pshufhw XMM,XMM/m128,imm8(0~255)
先把源存储器的低64位内容送入目的寄存器的低64位,然后用imm8将源存储器的高64位4个字选入目的寄存器的高64位,内存变量必须对齐内存16字节.
源寄存器高64位: b(11) | b(10) | b(01) | b(00)
目的寄存器高64位排列结果: b(00~11) | b(00~11) | b(00~11) | b(00~11)
当XMM0 = 3333 4444 5555 6666 1111111122222222 h
XMM1 = 7777 8888 9999 cccc 5555555566666666 h,执行pshufhw XMM0,XMM1,10 10 01 10 b
则XMM0 = 8888 8888 9999 8888 5555555566666666 h

42. pshufd
pshufd XMM,XMM/m128,imm8(0~255)
将源存储器的4个双字由imm8指定选入目的寄存器,内存变量必须对齐内存16字节.
源寄存器: b(11) | b(10) | b(01) | b(00)
目的寄存器排列结果: b(00~11) | b(00~11) | b(00~11) | b(00~11)
当XMM1 = 11111111 22222222 33333333 44444444 h,执行pshufd XMM0,XMM1,11 01 01 10b
则XMM0 = 11111111 33333333 33333333 22222222 h

9 数据类型操作

43. cvtpi2ps
cvtpi2ps XMM,MM/m64
源存储器64位两个32位有符号(补码)整数转为两个单精度浮点数,放入目的寄存器低64中,高64位不变.

44. cvtsi2ss
cvtsi2ss XMM,r32/m32
源存储器1个32位有符号(补码)整数转为1个单精度浮点数,放入目的寄存器低32中,高96位不变.

45. cvtps2pi
cvtps2pi MM,XMM/m64
把源存储器低64位两个32位单精度浮点数转为两个32位有符号(补码)整数,放入目的寄存器

46. cvttps2pi
cvttps2pi MM,XMM/m64
类似于cvtps2pi,截断取整.

47. cvtss2si
cvtss2si r32,XMM/m32
把源存储器低32位1个单精度浮点数转为1个32位有符号(补码)整数,放入目的寄存器.

48. cvttss2si
 cvttss2si r32,XMM/m32
类似cvtss2si,截断取整.

49. cvtps2pd
cvtps2pd XMM,XMM/m64
把源存储器低64位两个单精度浮点数变成两个双精度浮点数,结果送入目的寄存器.

50. cvtss2sd
cvtss2sd XMM,XMM/m32
把源存储器低32位1个单精度浮点数变成1个双精度浮点数,结果送入目的寄存器的低64位,高64位不变.

51. cvtpd2ps
把源存储器两个双精度浮点数变成两个单精度浮点数,结果送入目的寄存器的低64位,高64位清零, 内存变量必须对齐内存16字节.
^特殊状态 ^3.14E5 (表示负无穷大)

52. cvtsd2ss
cvtsd2ss XMM,XMM/m64
把源存储器低64位1个双精度浮点数变成1个单精度浮点数,结果送入目的寄存器的低32位,高96位不变.

53. cvtpd2pi
cvtpd2pi MM,XMM/m128
把源存储器两个双精度浮点数变成两个双字有符号整数,结果送入目的寄存器,内存变量必须对齐内存16字节. 如果结果大于所能表示的范围,那么转化为80000000h(正数也转为此值).

54. cvttpd2pi
cvttpd2pi MM,XMM/m128
类似于cvtpd2pi,截断取整.

55. cvtpi2pd
cvtpi2pd XMM,MM/m64
把源存储器两个双字有符号整数变成两个双精度浮点数,结果送入目的寄存器.

56. cvtpd2dq
cvtpd2dq XMM,XMM/m128
把源存储器两个双精度浮点数变成两个双字有符号整数(此运算与cvtpd2pi类似但目的寄存器变为XMM), 结果送入目的寄存器的低64位,高64位清零,内存变量必须对齐内存16字节.

57. cvttpd2dq
cvttpd2dq XMM,XMM/m128
类似于cvtpd2dq,为截断取整.

58. cvtdq2pd
cvtdq2pd XMM,XMM/m128
把源存储器低64位两个双字有符号整数变成两个双精度浮点数,结果送入目的寄存器,内存变量必须对齐内存16字节.

59. cvtsd2si
cvtsd2si r32,XMM/m64
把源存储器低64位1个双精度浮点数变成1个双字有符号整数,结果送入目的寄存器.

60. cvttsd2si
cvttsd2si r32,XMM/m64
类似于cvtsd2si,截断取整.

61. cvtsi2sd
cvtsi2sd XMM,r32/m32
把源存储器1个双字有符号整数变成1个双精度浮点数,结果送入目的寄存器的低64位,高64位不变.

62. cvtps2dq
cvtps2dq XMM,XMM/m128
把源存储器4个单精度浮点数变成4个双字有符号整数,结果送入目的寄存器,内存变量必须对齐内存16字节.

63. cvttps2dq
cvttps2dq XMM,XMM/m128
类似于cvtps2dq,截断取整.

64. cvtdq2ps
cvtdq2ps XMM,XMM/m128
把源存储器4个双字有符号整数变成4个单精度浮点数,结果送入目的寄存器,内存变量必须对齐内存16字节.

9 备注

1.        MMX指令有8个64位寄存器(MM0~MM7),不过可惜都是借的FPU的, FPU原来有8个80位寄存器(st(0)~st(7)),现在用在了MMX上,所以用之后要加上一条EMMS指令,用以复位.

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,我们可以了解到SSE指令集是一种针对英特尔CPU的指令集扩展,可以加速向量运算。而warpAffine是OpenCV中的一个函数,用于对图像进行仿射变换。为了加速warpAffine函数,我们可以使用SSE2指令集。 下面是使用SSE2指令集加速warpAffine的步骤和代码实现: 1. 首先,我们需要将图像数据转换为SSE2数据类型。可以使用_mm_loadu_si128函数将8个像素点的数据加载到一个__m128i类型的变量中。 2. 接下来,我们需要对图像进行仿射变换。可以使用_mm_setr_ps函数将仿射变换矩阵中的元素加载到一个__m128类型的变量中,然后使用_mm_mul_ps函数将该变量与图像数据中的像素点进行矩阵乘法运算。 3. 最后,我们需要将SSE2数据类型转换回普通的图像数据类型。可以使用_mm_storeu_si128函数将__m128i类型的变量中的数据存储到图像数据中。 下面是使用SSE2指令集加速warpAffine的代码实现: ```python import cv2 import numpy as np import time import os import sys import math import copy from numba import jit import numexpr as ne import matplotlib.pyplot as plt import pandas as pd import seaborn as sns import scipy.stats as stats import scipy.signal as signal import scipy.interpolate as interpolate import scipy.optimize as optimize import scipy.spatial.distance as distance import scipy.ndimage as ndimage import scipy.io as io import skimage.io as skio import skimage.transform as sktransform import skimage.color as skcolor import skimage.filters as skfilters import skimage.segmentation as skseg def warpAffine_sse2(img, M): rows, cols = img.shape[:2] dst = np.zeros((rows, cols), dtype=np.uint8) M = np.array(M).astype(np.float32) M = np.vstack([M, [0, 0, 1]]) M_inv = cv2.invertAffineTransform(M) M_inv = np.array(M_inv).astype(np.float32) for i in range(rows): for j in range(cols): x, y = np.dot(M_inv, np.array([j, i, 1])) if x >= 0 and x < cols and y >= 0 and y < rows: x1, y1 = int(x), int(y) x2, y2 = x1 + 1, y1 + 1 if x2 < cols and y2 < rows: p1 = _mm_loadu_si128(img[y1, x1:x1+8]) p2 = _mm_loadu_si128(img[y2, x1:x1+8]) p3 = _mm_loadu_si128(img[y1, x2:x2+8]) p4 = _mm_loadu_si128(img[y2, x2:x2+8]) fx1 = x - x1 fx2 = 1 - fx1 fy1 = y - y1 fy2 = 1 - fy1 w1 = _mm_setr_ps(fx2 * fy2, fx1 * fy2, fx2 * fy1, fx1 * fy1) w2 = _mm_setr_ps(1, 1, 1, 1) p = _mm_add_ps(_mm_add_ps(_mm_mul_ps(p1, w1), _mm_mul_ps(p2, _mm_mul_ps(w2, _mm_set1_ps(fy1)))), _mm_add_ps(_mm_mul_ps(p3, _mm_mul_ps(w2, _mm_set1_ps(fx1))), _mm_mul_ps(p4, _mm_mul_ps(w2, _mm_mul_ps(_mm_set1_ps(fx1), _mm_set1_ps(fy1)))))) _mm_storeu_si128(dst[i, j:j+8], p) return dst # 定义SSE2指令集函数 def _mm_loadu_si128(p): return np.frombuffer(p, dtype=np.uint8) def _mm_setr_ps(a, b, c, d): return np.array([a, b, c, d], dtype=np.float32) def _mm_add_ps(a, b): return a + b def _mm_mul_ps(a, b): return a * b def _mm_set1_ps(a): return np.array([a, a, a, a], dtype=np.float32) # 测试代码 img = cv2.imread('test.jpg', 0) rows, cols = img.shape[:2] M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1) start = time.time() dst = warpAffine_sse2(img, M) end = time.time() print('Time:', end - start) cv2.imshow('img', img) cv2.imshow('dst', dst) cv2.waitKey(0) cv2.destroyAllWindows() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值