寄存器sse2指令集

合集下载

sse2指令集

sse2指令集

sse2指令集sse2指令集1移动指令:1. Movapsmovaps XMM,XMM/m128 movaps XMM/128,XMM把源存储器内容值送入目的寄存器,当有m128时,必须对齐内存16字节,也就是内存地址低4位为0.2. Movupsmovups XMM,XMM/m128 movaps XMM/128,XMM把源存储器内容值送入目的寄存器,但不必对齐内存16字节3. Movlpsmovlps XMM,m64把源存储器64位内容送入目的寄存器低64位,高64位不变,内存变量不必对齐内存16字节4. Movhpsmovhps XMM,m64把源存储器64位内容送入目的寄存器高64位,低64位不变,内存变量不必对齐内存16字节.5. Movhlpsmovhlps XMM,XMM把源寄存器高64位送入目的寄存器低64位,高64位不变.6. Movlhpsmovlhps XMM,XMM把源寄存器低64位送入目的寄存器高64位,低64位不变.7. movssmovss XMM,m32/XMM原操作数为m32时:dest[31-00] <== m32 dest[127-32] <== 0原操作数为XMM时: dest[31-00] <== src[31-00] dest[127-32]不变8. movmskpdmovmskpd r32,XMM取64位操作数符号位r32[0] <== XMM[63] r32[1] <== XMM[127] r32[31-2] <== 09. movmskpsmovmskps r32,XMM取32位操作数符号位r32[0] <== XMM[31] r32[1] <== XMM[63] r32[2] <== XMM[95] r32[3] <== XMM[127] r32[31-4] <== 010. pmovmskbpmovmskb 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] <== 011. movntpsmovntps m128,XMMm128 <== XMM 直接把XMM中的值送入m128,不经过cache,必须对齐16字节.12. Movntpdmovntpd m128,XMMm128 <== XMM 直接把XMM中的值送入m128,不经过cache,必须对齐16字节.13. Movntimovnti m32,r32m32 <== r32 把32寄存器的值送入m32,不经过cache.14. Movapdmovapd XMM,XMM/m128 movapd XMM/m128,XMM把源存储器内容值送入目的寄存器,当有m128时,必须对齐内存16字节15. Movupdmovupd XMM,XMM/m128 movapd XMM/m128,XMM把源存储器内容值送入目的寄存器,但不必对齐内存16字节.我感觉这两条指令同movaps 和 movups 指令一样,不过又不确定.16. Movlpdmovlpd XMM,m64 movlpd m64,XMM把源存储器64位内容送入目的寄存器低64位,高64位不变,内存变量不必对齐内存16字节17. Movhpdmovhpd XMM,m64 movhpd m64,XMM把源存储器64位内容送入目的寄存器高64位,低64位不变,内存变量不必对齐内存16字节.18. Movdqamovdqa XMM,XMM/m128 movdqa XMM/m128,XMM把源存储器内容值送入目的寄存器,当有m128时,必须对齐内存16字节.19. Movdqumovdqu XMM,XMM/m128 movdqu XMM/m128,XMM把源存储器内容值送入目的寄存器,但不必对齐内存16字节.20. movq2dqmovq2dq XMM,MM把源寄存器内容送入目的寄存器的低64位,高64位清零.21. movdq2qmovdq2q MM,XMM把源寄存器低64位内容送入目的寄存器.22. Movdmovd XMM,r32/m32 movd MM,r32/m32把源存储器32位内容送入目的寄存器的低32位,高96位清零.movd r32/m32,XMM movd r32/m32,MM把源寄存器的低32位内容送入目的存储器32位.23. Movqmovq XMM,XMM/m64 movq MM,MM/m64把源存储器低64位内容送入目的寄存器的低64位,高64位清零.movq m64,XMM把源寄存器的低64位内容送入目的存储器.2 加法操作1. addpsaddps XMM,XMM/m128源存储器内容按双字对齐,共4个单精度浮点数与目的寄存器相加,结果送入目的寄存器,内存变量必须对齐内存16字节2. addsaddss XMM,XMM/m32源存储器的低32位1个单精度浮点数与目的寄存器的低32位1个单精度浮点数相加,结果送入目的寄存器的低32位高96位不变,内存变量不必对齐内存16字节3. addpdaddpd XMM,XMM/m128源存储器内容按四字对齐,共两个双精度浮点数与目的寄存器相加,结果送入目的寄存器,内存变量必须对齐内存16字节.4. addsdaddsd XMM,XMM/m64源存储器的低64位1个双精度浮点数与目的寄存器的低64位1个双精度浮点数相加,结果送入目的寄存器的低64位, 高64位不变,内存变量不必对齐内存16字节5. padddpaddd XMM,XMM/m128把源存储器与目的寄存器按双字对齐无符号整数普通相加,结果送入目的寄存器,内存变量必须对齐内存16字节.6. Paddqpaddq XMM,XMM/m128把源存储器与目的寄存器按四字对齐无符号整数普通相加,结果送入目的寄存器,内存变量必须对齐内存16字节.7. Paddqpaddq MM,MM/m64把源存储器与目的寄存器四字无符号整数普通相加,结果送入目的寄存器.8. Pmaddwdpmaddwd 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*b79. Paddsbpaddsb XMM,XMM/m128 paddsb MM,MM/m64源存储器与目的寄存器按字节对齐有符号补码饱和相加,内存变量必须对齐内存16字节.10. paddswpaddsw XMM,XMM/m128源存储器与目的寄存器按字对齐有符号补码饱和相加,内存变量必须对齐内存16字节.11. paddusbpaddusb XMM,XMM/m128源存储器与目的寄存器按字节对齐无符号饱和相加,内存变量必须对齐内存16字节.12. Padduswpaddusw XMM,XMM/m128源存储器与目的寄存器按字对齐无符号饱和相加,内存变量必须对齐内存16字节.13. Paddbpaddb XMM,XMM/m128源存储器与目的寄存器按字节对齐无符号普通相加,内存变量必须对齐内存16字节.14. Paddwpaddw XMM,XMM/m128源存储器与目的寄存器按字对齐无符号普通相加,内存变量必须对齐内存16字节.15. Padddpaddd XMM,XMM/m128源存储器与目的寄存器按双字对齐无符号普通相加,内存变量必须对齐内存16字节.16. Paddqpaddq XMM,XMM/m128源存储器与目的寄存器按四字对齐无符号普通相加,内存变量必须对齐内存16字节.17.3 减法操作1. subpssubps XMM,XMM/m128源存储器内容按双字对齐,共4个单精度浮点数与目的寄存器相减(目的减去源),结果送入目的寄存器, 内存变量必须对齐内存16字节.2. Subsssubss XMM,XMM/m32源存储器的低32位1个单精度浮点数与目的寄存器的低32位1个单精度浮点数相减(目的减去源), 结果送入目的寄存器的低32位,高96位不变,内存变量不必对齐内存16字节3. Subpdsubpd XMM,XMM/m128把目的寄存器内容按四字对齐,两个双精度浮点数,减去源存储器两个双精度浮点数, 结果送入目的寄存器,内存变量必须对齐内存16字节.4. subsdsubsd XMM,XMM/m128把目的寄存器的低64位1个双精度浮点数,减去源存储器低64位1个双精度浮点数,结果送入目的寄存器的低64位, 高64位不变,内存变量不必对齐内存16字节5. Psubdpsubd XMM,XMM/m128把目的寄存器与源存储器按双字对齐无符号整数普通相减,结果送入目的寄存器, 内存变量必须对齐内存16字节.(目的减去源)6. Psubqpsubq XMM,XMM/m128把目的寄存器与源存储器按四字对齐无符号整数普通相减,结果送入目的寄存器, 内存变量必须对齐内存16字节.(目的减去源)7. Psubqpsubq MM,MM/m64把目的寄存器与源存储器四字无符号整数普通相减,结果送入目的寄存器.(目的减去源)8. psubsbpsubsb XMM,XMM/m128源存储器与目的寄存器按字节对齐有符号补码饱和相减(目的减去源),内存变量必须对齐内存16字节.9. Psubswpsubsw XMM,XMM/m128源存储器与目的寄存器按字对齐有符号补码饱和相减(目的减去源),内存变量必须对齐内存16字节.10. Psubusbpsubusb XMM,XMM/m128源存储器与目的寄存器按字节对齐无符号饱和相减(目的减去源),内存变量必须对齐内存16字节.11. Psubuswpsubusw XMM,XMM/m128源存储器与目的寄存器按字对齐无符号饱和相减(目的减去源),内存变量必须对齐内存16字节.12. psubbpsubb XMM,XMM/m128源存储器与目的寄存器按字节对齐无符号普通相减(目的减去源),内存变量必须对齐内存16字节.13. Psubwpsubw XMM,XMM/m128源存储器与目的寄存器按字对齐无符号普通相减(目的减去源),内存变量必须对齐内存16字节.14. Psubdpsubd XMM,XMM/m128源存储器与目的寄存器按双字对齐无符号普通相减(目的减去源),内存变量必须对齐内存16字节.15. Psubqpsubq XMM,XMM/m128源存储器与目的寄存器按四字对齐无符号普通相减(目的减去源),内存变量必须对齐内存16字节.16.4 比较操作1. Maxpsmaxps XMM,XMM/m128源存储器4个单精度浮点数与目的寄存器4个单精度浮点数比较,较大数放入对应目的寄存器,内存变量必须对齐内存16字节.2. Maxssmaxss XMM,XMM/m32源存储器低32位1个单精度浮点数与目的寄存器低32位1个单精度浮点数比较,较大数放入目的寄存器低32位,高96位不变内存变量不必对齐内存16字节3. Minpsminps XMM,XMM/m128源存储器4个单精度浮点数与目的寄存器4个单精度浮点数比较,较小数放入对应目的寄存器,内存变量必须对齐内存16字节.4. minssminss XMM,XMM/m32源存储器低32位1个单精度浮点数与目的寄存器低32位1个单精度浮点数比较,较小数放入目的寄存器低32位,高96位不变内存变量不必对齐内存16字节5. cmppscmpps XMM0,XMM1,imm8 imm8是立即数范围是0~7根据imm8的值进行4对单精度浮点数的比较,符合imm8的就置目的寄存器对应的32位全1,否则全0当imm8 = 0时,目的寄存器等于原寄存器数时,置目的寄存器对应的32位全1,否则全0imm8 = 1 时,目的寄存器小于原寄存器数时,置目的寄存器对应的32位全1,否则全0imm8 = 2 时,目的寄存器小于等于原寄存器数时,置目的寄存器对应的32位全1,否则全0imm8 = 4 时,目的寄存器不等于原寄存器数时,置目的寄存器对应的32位全1,否则全0imm8 = 5 时,目的寄存器大于等于原寄存器数时,置目的寄存器对应的32位全1,否则全0imm8 = 6 时,目的寄存器大于原寄存器数时,置目的寄存器对应的32位全1,否则全06. pcmpeqbpcmpeqb XMM,XMM/m128目的寄存器与源存储器按字节比较,如果对应字节相等,就置目的寄存器对应字节为0ffh,否则为00h内存变量必须对齐内存16字节.7. Pcmpeqwpcmpeqw XMM,XMM/m128目的寄存器与源存储器按字比较,如果对应字相等,就置目的寄存器对应字为0ffffh,否则为0000h, 内存变量必须对齐内存16字节8. Pcmpeqdpcmpeqd XMM,XMM/m128目的寄存器与源存储器按双字比较,如果对应双字相等,就置目的寄存器对应双字为0ffffffffh,否则为00000000h内存变量必须对齐内存16字节9. Pcmpgtbpcmpgtb XMM,XMM/m128目的寄存器与源存储器按字节(有符号补码)比较,如果目的寄存器对应字节大于源存储器,就置目的寄存器对应字节为0ffh, 否则为00h,内存变量必须对齐内存16字节10. Pcmpgtwpcmpgtw XMM,XMM/m128目的寄存器与源存储器按字(有符号补码)比较,如果目的寄存器对应字大于源存储器,就置目的寄存器对应字为0ffffh, 否则为0000h,内存变量必须对齐内存16字节.11. Pcmpgtdpcmpgtd XMM,XMM/m128目的寄存器与源存储器按双字(有符号补码)比较,如果目的寄存器对应双字大于源存储器, 就置目的寄存器对应双字为0ffffffffh,否则为00000000h,内存变量必须对齐内存16字节.5 计算操作1. rcppsrcpps XMM,XMM/m128源存储器4个单精度浮点数的倒数放入对应目的寄存器,内存变量必须对齐内存16字节注:比如2.0E0的倒数为1÷2.0E0 = 5.0E-1, 这操作只有12bit的精度2. rcpssrcpss XMM,XMM/32源存储器低32位1个单精度浮点数的倒数放入目的寄存器低32位,高96位不变3. rsqrtpsrsqrtps XMM,XMM/m128源存储器4个单精度浮点数的开方的倒数放入对应目的寄存器,内存变量必须对齐内存16字节. 比如2.0E0的开方的倒数为1÷√2.0E0 ≈ 7.0711E-1, 这操作只有12bit的精度.4. Rsqrtssrsqrtss XMM,XMM/32源存储器低32位1个单精度浮点数的开方的倒数放入目的寄存器低32位,高96位不变,内存变量不必对齐内存16字节.5. Pavgbpavgb MM,MM/m64 pavgb XMM,XMM/m128把源存储器与目的寄存器按字节无符号整数相加,再除以2,结果四舍五入为整数放入目的寄存器, 源存储器为m128时,内存变量必须对齐内存16字节. 注:此运算不会产生溢出.6. Pavgwpavgw MM,MM/m64 pavgw XMM,XMM/m128把源存储器与目的寄存器按字无符号整数相加,再除以2,结果四舍五入为整数放入目的寄存器, 源存储器为m128时,内存变量必须对齐内存16字节.7. Sqrtpdsqrtpd XMM,XMM/m128源存储器两个双精度浮点数的开方放入对应目的寄存器,内存变量必须对齐内存16字节.8. Sqrtsdsqrtsd XMM,XMM/m128源存储器低64位1个双精度浮点数的开方放入目的寄存器低64位,高64位不变,内存变量不必对齐内存16字节6 乘法操作1. Mulpsmulps XMM,XMM/m128源存储器内容按双字对齐,共4个单精度浮点数与目的寄存器相乘,结果送入目的寄存器,内存变量必须对齐内存16字节.2. Mulssmulss XMM,XMM/32源存储器的低32位1个单精度浮点数与目的寄存器的低32位1个单精度浮点数相乘,结果送入目的寄存器的低32位, 高96位不变,内存变量不必对齐内存16字节3. Mulpdmulpd XMM,XMM/m128源存储器内容按四字对齐,共两个双精度浮点数与目的寄存器相乘,结果送入目的寄存器,内存变量必须对齐内存16字节4. Mulsdmulsd XMM,XMM/m128源存储器的低64位1个双精度浮点数与目的寄存器的低64位1个双精度浮点数相乘,结果送入目的寄存器的低64位, 高64位不变,内存变量不必对齐内存16字节5. Pmuludqpmuludq XMM,XMM/m128把源存储器与目的寄存器的低32位无符号整数相乘,结果变为64位,送入目的寄存器低64位, 把源存储器与目的寄存器的高64位的低32位无符号整数相乘,结果变为64位,送入目的寄存器高64位内存变量必须对齐内存16字节.高64位 | 低64位目的寄存器: a0 | a1 | a2 | a3源存储器: b0 | b1 | b2 | b3目的寄存器结果: b1*a1 | b3*a36. Pmuludqpmuludq MM,MM/m64把源存储器与目的寄存器的低32位无符号整数相乘,结果变为64位,送入目的寄存器.7. pmulhwpmulhw XMM,XMM/m128源存储器与目的寄存器按字对齐有符号补码饱和相乘,取结果的高16位放入目的寄存器对应字中. 内存变量必须对齐内存16字节8. pmullwpmullw XMM,XMM/m128源存储器与目的寄存器按字对齐有符号补码饱和相乘,取结果的低16位放入目的寄存器对应字中. 内存变量必须对齐内存16字节.9.7 除法操作1. Divpsdivps XMM,XMM/m128目的寄存器共4个单精度浮点数除以源存储器4个单精度浮点数,结果送入目的寄存器,内存变量必须对齐内存16字节.2. Divssdivss XMM,XMM/32目的寄存器低32位1个单精度浮点数除以源存储器低32位1个单精度浮点数,结果送入目的寄存器的低32位, 高96位不变,内存变量不必对齐内存16字节3. Divpddivpd XMM,XMM/m128目的寄存器共两个双精度浮点数除以源存储器两个双精度浮点数,结果送入目的寄存器,内存变量必须对齐内存16字节4. Divsddivsd XMM,XMM/m128目的寄存器低64位1个双精度浮点数除以源存储器低64位1个双精度浮点数,结果送入目的寄存器的低64位, 高64位不变,内存变量不必对齐内存16字节.8 位操作1. Andpsandps XMM,XMM/m128源存储器128个二进制位'与'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.2. Orpsorps XMM,XMM/m128源存储器128个二进制位'或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.3. Xorpsxorps XMM,XMM/m128源存储器128个二进制位'异或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.4. Unpckhpsunpckhps XMM,XMM/m128源存储器与目的寄存器高64位按双字交错排列,结果送入目的寄存器,内存变量必须对齐内存16字节.高64位 | 低64位目的寄存器: a0 | a1 | a2 | a3源存储器: b0 | b1 | b2 | b3目的寄存器结果: b0 | a0 | b1 | a15. Unpcklpsunpcklps XMM,XMM/m128源存储器与目的寄存器低64位按双字交错排列,结果送入目的寄存器,内存变量必须对齐内存16字节高64位 | 低64位目的寄存器: a0 | a1 | a2 | a3源存储器: b0 | b1 | b2 | b3目的寄存器结果: b2 | a2 | b3 | a36. Pextrwpextrw 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 87. Pinsrwpinsrw 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 88. Pmaxswpmaxsw MM,MM/m64 pmaxsw XMM,XMM/m128把源存储器与目的寄存器按字有符号(补码)整数比较,大数放入目的寄存器对应字, 源存储器为m128时,内存变量必须对齐内存16字节9. Pmaxubpmaxub MM,MM/m64 pmaxsw XMM,XMM/m128把源存储器与目的寄存器按字节无符号整数比较,大数放入目的寄存器对应字节, 源存储器为m128时,内存变量必须对齐内存16字节.10. pminswpminsw MM,MM/m64 pmaxsw XMM,XMM/m128把源存储器与目的寄存器按字有符号(补码)整数比较,较小数放入目的寄存器对应字, 源存储器为m128时,内存变量必须对齐内存16字节.11. Pminubpminub MM,MM/m64 pmaxsw XMM,XMM/m128把源存储器与目的寄存器按字节无符号整数比较,较小数放入目的寄存器对应字节, 源存储器为m128时,内存变量必须对齐内存16字节12. Maxpdmaxpd XMM,XMM/m128源存储器两个双精度浮点数与目的寄存器两个双精度浮点数比较,较大数放入对应目的寄存器,内存变量必须对齐内存16字节.13. Maxsdmaxsd XMM,XMM/m128源存储器低64位1个双精度浮点数与目的寄存器低64位1个双精度浮点数比较,较大数放入目的寄存器低64位,高64位不变内存变量不必对齐内存16字节.14. Minpdminpd XMM,XMM/m128源存储器两个双精度浮点数与目的寄存器两个双精度浮点数比较,较小数放入对应目的寄存器,内存变量必须对齐内存16字节.15. Minsdminsd XMM,XMM/m128源存储器低64位1个双精度浮点数与目的寄存器低64位1个双精度浮点数比较,较小数放入目的寄存器低64位,高64位不变内存变量不必对齐内存16字节.16. Andpdandpd XMM,XMM/m128源存储器128个二进制位'与'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.17. Andnpdandnpd XMM,XMM/m128目的寄存器128个二进制位先取'非',再'与'源存储器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节18. Orpdorpd XMM,XMM/m128源存储器128个二进制位'或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.19. Xorpdxorpd XMM,XMM/m128源存储器128个二进制位'异或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.20. Pslldqpslldq XMM,imm8把目的寄存器128位按imm8(立即数)指定字节数逻辑左移,移出的字节丢失.imm8 == 1时,代表左移8位,imm8 == 2时,代表左移16位.21. Psrldqpsrldq XMM,imm8把目的寄存器128位按imm8(立即数)指定字节数逻辑右移,移出的字节丢失.imm8 == 1时,代表右移8位,imm8 == 2时,代表右移16位.22. Psllwpsllw XMM,XMM/m128 psllw XMM,imm8把目的寄存器按字由源存储器(或imm8 立即数)指定位数逻辑左移,移出的位丢失. 低字移出的位不会移入高字,内存变量必须对齐内存16字节.23. Psrlwpsrlw XMM,XMM/m128 psrlw XMM,imm8把目的寄存器按字由源存储器(或imm8 立即数)指定位数逻辑右移,移出的位丢失.高字移出的位不会移入低字,内存变量必须对齐内存16字节.24. Pslldpslld XMM,XMM/m128 pslld XMM,XMM imm8把目的寄存器按双字由源存储器(或imm8 立即数)指定位数逻辑左移,移出的位丢失. 低双字移出的位不会移入高双字,内存变量必须对齐内存16字节.25. Psrldpsrld XMM,XMM/m128 psrld XMM,imm8把目的寄存器按双字由源存储器(或imm8 立即数)指定位数逻辑右移,移出的位丢失.高双字移出的位不会移入低双字,内存变量必须对齐内存16字节.pandpand XMM,XMM/m128源存储器128个二进制位'与'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节. 我发现与andpd功能差不多,就不知其它特性是否一样26. Pandnpandn XMM,XMM/m128目的寄存器128个二进制位先取'非',再'与'源存储器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节27. Porpor XMM,XMM/m128源存储器128个二进制位'或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.28. Pxorpxor XMM,XMM/m128源存储器128个二进制位'异或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.29. packuswbpackuswb 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| a730. packsswbpacksswb 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| a731. packssdwpackssdw 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 | a332. punpckldqpunpckldq XMM,XMM/m128把源存储器与目的寄存器低64位按双字交错排列,内存变量必须对齐内存16字节.高64位 | 低64位目的寄存器: a0 | a1 | a2 | a3源寄存器: b0 | b1 | b2 | b3目的寄存器排列结果: b2 | a2 | b3 | a333. punpckhdq把源存储器与目的寄存器高64位按双字交错排列,内存变量必须对齐内存16字节.高64位 | 低64位目的寄存器: a0 | a1 | a2 | a3源寄存器: b0 | b1 | b2 | b3目的寄存器排列结果: b0 | a0 | b1 | a134. 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 | a735. punpckhwdpunpckhwd 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 | a336. punpcklbwpunpcklbw 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| aF37. 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| a738. shufpsshufps 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 h39. shufpdshufpd 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 hXMM1 = 5555555566666666 aaaaaaaacccccccc h,执行shufpd XMM0,XMM1,101001 1 0 b则XMM0 = 5555555566666666 3333333344444444 h40. pshuflwpshuflw 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 hXMM1 = 5555555566666666 7777 8888 9999 cccc h,执行pshuflw XMM0,XMM1,10 10 01 10 b则XMM0 = 5555555566666666 8888 8888 9999 8888 h41. pshufhwpshufhw 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 hXMM1 = 7777 8888 9999 cccc 5555555566666666 h,执行pshufhw XMM0,XMM1,10 10 01 10 b则XMM0 = 8888 8888 9999 8888 5555555566666666 h42. pshufdpshufd 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 h9 数据类型操作43. cvtpi2pscvtpi2ps XMM,MM/m64源存储器64位两个32位有符号(补码)整数转为两个单精度浮点数,放入目的寄存器低64中,高64位不变.44. cvtsi2sscvtsi2ss XMM,r32/m32源存储器1个32位有符号(补码)整数转为1个单精度浮点数,放入目的寄存器低32中,高96位不变.45. cvtps2picvtps2pi MM,XMM/m64把源存储器低64位两个32位单精度浮点数转为两个32位有符号(补码)整数,放入目的寄存器46. cvttps2picvttps2pi MM,XMM/m64类似于cvtps2pi,截断取整.47. cvtss2sicvtss2si r32,XMM/m32把源存储器低32位1个单精度浮点数转为1个32位有符号(补码)整数,放入目的寄存器.48. cvttss2sicvttss2si r32,XMM/m32类似cvtss2si,截断取整.49. cvtps2pdcvtps2pd XMM,XMM/m64把源存储器低64位两个单精度浮点数变成两个双精度浮点数,结果送入目的寄存器.50. cvtss2sdcvtss2sd XMM,XMM/m32把源存储器低32位1个单精度浮点数变成1个双精度浮点数,结果送入目的寄存器的低64位,高64位不变.51. cvtpd2ps把源存储器两个双精度浮点数变成两个单精度浮点数,结果送入目的寄存器的低64位,高64位清零, 内存变量必须对齐内存16字节.^特殊状态^3.14E5 (表示负无穷大)52. cvtsd2sscvtsd2ss XMM,XMM/m64把源存储器低64位1个双精度浮点数变成1个单精度浮点数,结果送入目的寄存器的低32位,高96位不变.53. cvtpd2picvtpd2pi MM,XMM/m128把源存储器两个双精度浮点数变成两个双字有符号整数,结果送入目的寄存器,内存变量必须对齐内存16字节. 如果结果大于所能表示的范围,那么转化为80000000h(正数也转为此值).54. cvttpd2picvttpd2pi MM,XMM/m128类似于cvtpd2pi,截断取整.55. cvtpi2pdcvtpi2pd XMM,MM/m64把源存储器两个双字有符号整数变成两个双精度浮点数,结果送入目的寄存器.56. cvtpd2dqcvtpd2dq XMM,XMM/m128把源存储器两个双精度浮点数变成两个双字有符号整数(此运算与cvtpd2pi类似但目的寄存器变为XMM), 结果送入目的寄存器的低64位,高64位清零,内存变量必须对齐内存16字节.57. cvttpd2dqcvttpd2dq XMM,XMM/m128。

cpu指令集

cpu指令集

CPU_多媒体指令集解释CPU依靠指令来计算和控制系统,每款CPU在设计时就规定了一系列与其硬件电路相配合的指令系统。

指令的强弱也是CPU的重要指标,指令集是提高微处理器效率的最有效工具之一。

从现阶段的主流体系结构讲,指令集可分为复杂指令集和精简指令集两部分,而从具体运用看,如Intel的MMX(Multi Media Extended)、SSE、 SSE2(Streaming-Single instruction multiple data-Extensions 2)和AMD的3DNow!等都是CPU的扩展指令集,分别增强了CPU的多媒体、图形图象和Internet等的处理能力。

我们通常会把CPU的扩展指令集称为"CPU的指令集"。

精简指令集的运用在最初发明计算机的数十年里,随着计算机功能日趋增大,性能日趋变强,内部元器件也越来越多,指令集日趋复杂,过于冗杂的指令严重的影响了计算机的工作效率。

后来经过研究发现,在计算机中,80%程序只用到了20%的指令集,基于这一发现,RISC精简指令集被提了出来,这是计算机系统架构的一次深刻革命。

RISC体系结构的基本思路是:抓住CISC 指令系统指令种类太多、指令格式不规范、寻址方式太多的缺点,通过减少指令种类、规范指令格式和简化寻址方式,方便处理器内部的并行处理,提高VLSI器件的使用效率,从而大幅度地提高处理器的性能。

RISC指令集有许多特征,其中最重要的有:1. 指令种类少,指令格式规范:RISC指令集通常只使用一种或少数几种格式。

指令长度单一(一般4个字节),并且在字边界上对齐。

字段位置、特别是操作码的位置是固定的。

2. 寻址方式简化:几乎所有指令都使用寄存器寻址方式,寻址方式总数一般不超过5个。

其他更为复杂的寻址方式,如间接寻址等则由软件利用简单的寻址方式来合成。

3. 大量利用寄存器间操作:RISC指令集中大多数操作都是寄存器到寄存器操作,只以简单的Load和Store操作访问内存。

指令集

指令集

CPU作为一台电脑中的核心,它的作用是无法替代的。

而CPU本身只是在块硅晶片上所集成的超大规模的集成电路,集成的晶体管数量可达到上亿个,是由非常先进复杂的制造工艺制造出来的,拥有相当高的科技含量。

然而如此一颗精密的芯片为什么能够控制一个庞大而复杂的电脑系统呢?这就是CPU中所集成的指令集。

所谓指令集,就是CPU中用来计算和控制计算机系统的一套指令的集合,而每一种新型的CPU在设计时就规定了一系列与其他硬件电路相配合的指令系统。

而指令集的先进与否,也关系到CPU的性能发挥,它也是CPU性能体现的一个重要标志。

CPU的指令集从主流的体系结构上分为精简指令集和复杂指令集,而在普通的计算机处理器基本上是使用的复杂指令集。

在计算机早期的发展过程中,CPU 中的指令集是没有划分类型的,而是都将各种程序需要相配合的指令集成到CPU 中,但是随着科技的进步,计算机的功能也越来越强大,计算机内部的元件也越来越多,而且越来越复杂,CPU的指令也相应的变得十分复杂,而在使用过程中,并不是每一条指令都要完全被执行,在技术人员的研究过程中发现,约有80%的程序只用到了20%的指令,而一些过于冗余的指令严重影响到了计算机的工作效率,就这一现象,精简指令集的概念就被提了出来。

精简指令集RISC就是(Reduced Instruction Set Computing)的缩写,而复杂指令集CISC则是(Complex Instruction Set Computing)的缩写。

它们之间的不同之处就在于RISC指令集的指令数目少,而且每条指令采用相同的字节长度,一般长度为4个字节,并且在字边界上对齐,字段位置固定,特别是操作码的位置。

而CISC指令集特点就是指令数目多而且复杂,每条指令的长度也不相等。

在操作上,RISC指令集中大多数操作都是寄存器到寄存器之间的操作,只以简单的Load(读取)和Sotre(存储)操作访问内存地址。

因此,每条指令中访问的内存地址不会超过1个,指令访问内存的操作不会与算术操作混在一起。

CPU指令集MMXSSESSE2SSE33

CPU指令集MMXSSESSE2SSE33

CPU指令集MMX SSE SSE2SSE3 3原文地址:CPU指令集:MMX SSE SSE2 SSE3 3DNow!AMD64 EM64T作者:老鬼MMX:MMX(Multi Media eXtension多媒体扩展指令)指令集是Intel公司在1996年为旗下的Pentium系列处理器所开发的一项多媒体指令增强技术。

MMX指令集中包括了57条多媒体指令,通过这些指令可以一次性处理多个数据,在处理结果超过实际处理能力的时候仍能够进行正常处理,如果在软件的配合下,可以得到更强的处理性能。

使用MMX指令集的好处就是当时所使用的操作系统可以在不做任何改变的情况下执行MMX指令。

但是,MMX指令集的问题也是比较明显的,MMX指令集不能与X86的浮点运算指令同时执行,必须做密集式的交错切换才可以正常执行,但是这样一来,就会造成整个系统运行速度的下降。

SSE:SSE是Streaming SIMD Extension(SIMD扩展指令集)的缩写,而其中SIMD的为含意为Single Istruction Multiple Data(单指令多数据),所以SSE指令集也叫单指令多数据流扩展。

该指令集最先运用于Intel的PentiumIII系列处理器,其实在Pentium III推出之前,Intel方面就已经泄漏过关于KNI(Katmai New Instruction)指令集的消息。

这个KNI指令集也就是SSE指令集的前身,当时也有不少的媒体将该指令集称之为MMX2指令集,但是Intel方面却从没有发布有关MMX2指令集的消息。

最后在Intel推出Pentium III处理器的时候,SSE指令集也终于水落石出。

SSE指令集是为提高处理器浮点性能而开发的扩展指令集,它共有70条指令,其中包含提高3D图形运算效率的50条SIMD浮点运算指令、12条MMX整数运算增强指令、8条优化内存中的连续数据块传输指令。

理论上这些指令对当时流行的图像处理、浮点运算、3D运算、多媒体处理等众多多媒体的应用能力起到全面提升的作用。

SSE体系结构与编程

SSE体系结构与编程

// 计算y’(i)和y’(i+1) mx0 = _mm_mul_pd(tx, WM->dm10); //tx, ty, tz已经事先读入 mx1 = _mm_mul_pd(ty, WM->dm11); mx2 = _mm_mul_pd(tz, WM->dm12); mx0 = _mm_add_pd(mx0, _mm_add_pd(mx1, _mm_add_pd(mx2, WM->dm13))); _mm_store_pd(vertex.y + i, mx0); // 计算z’(i)和z’(i+1) mx0 = _mm_mul_pd(tx, WM->dm20); mx1 = _mm_mul_pd(ty, WM->dm21); mx2 = _mm_mul_pd(tz, WM->dm22); mx0 = _mm_add_pd(mx0, _mm_add_pd(mx1, _mm_add_pd(mx2, WM->dm23))); _mm_store_pd(vertex.z + i, mx0); //计算z’(i)和z’(i+1) mx0 = _mm_mul_pd(tx, WM->dm30); mx1 = _mm_mul_pd(ty, WM->dm31); mx2 = _mm_mul_pd(tz, WM->dm32); mx0 = _mm_add_pd(mx0, _mm_add_pd(mx1, _mm_add_pd(mx2, WM->dm33))); _mm_store_pd(vertex.w + i, mx0); }
SSE程序实例
两种不同的数据结构 数组-结构(the array-of-structures format(AoS) ) 结构-数组(the structures-of-arrays data format(SoA) )

sse2 加速原理

sse2 加速原理

sse2 加速原理SSE2加速原理SSE2(Streaming SIMD Extensions 2)是英特尔公司推出的一种SIMD指令集扩展,用于提高计算机处理器的运算速度。

SSE2指令集主要针对多媒体应用程序的加速优化,通过并行处理多个数据,可以显著提高计算效率。

SSE2的加速原理可以简单概括为以下几个方面:1. 数据并行处理:SSE2指令集引入了128位寄存器,可以同时处理更多的数据。

与之前的MMX技术相比,SSE2可以一次性处理更多的数据,从而加快计算速度。

SSE2提供了一系列的数据运算指令,如加法、减法、乘法、除法等,可以对多个数据同时进行处理,大大提高了计算效率。

2. 数据对齐优化:SSE2指令集要求数据在内存中的存储地址必须按照一定的规则进行对齐。

对齐指的是数据存储在内存中的起始地址必须是某个特定值的倍数。

通过对数据进行对齐优化,可以提高数据传输的效率。

SSE2提供了一些对齐操作指令,可以有效地利用CPU的缓存,减少数据访问延迟。

3. 数据重排优化:SSE2指令集提供了一些数据重排的指令,可以将不连续的数据重新排列成连续的数据,从而提高数据访问的效率。

数据重排可以减少数据访问的延迟,提高数据的带宽利用率。

4. 浮点运算优化:SSE2指令集对浮点运算进行了优化,引入了一些新的浮点运算指令,如乘法、除法和开方等。

这些指令可以在一个时钟周期内完成多个浮点运算,提高浮点运算的效率。

5. 字符串处理优化:SSE2指令集还提供了一些字符串处理的指令,可以加速字符串的匹配、查找和替换等操作。

字符串处理是许多应用程序中的常见操作,通过使用SSE2指令集进行优化,可以提高字符串处理的速度。

SSE2加速原理是通过数据并行处理、数据对齐优化、数据重排优化、浮点运算优化和字符串处理优化等方式,提高计算机处理器的运算速度。

SSE2指令集的引入极大地改进了计算机的计算能力,使得多媒体应用程序能够更加流畅地运行,并且提高了计算机的整体性能。

SSE是指令集

SSE是指令集

SSESSE是指令集的简称,它包括70条指令,其中包含单指令多数据浮点计算、以及额外的SIMD整数和高速缓存控制指令。

其优势包括:更高分辨率的图像浏览和处理、高质量音频、MPEG2视频、同时MPEG2加解密;语音识别占用更少CPU 资源;更高精度和更快响应速度。

目录编辑本段SSE(Streaming SIMD Extensions)是英特尔在AMD的3D Now!发布一年之后,在其计算机芯片Pentium III中引入的指令集,是MMX的超集。

AMD 后来在Athlon XP中加入了对这个指令集的支持。

这个指令集增加了对8个128位寄存器XMM0-XMM7的支持,每个寄存器可以存储4个单精度浮点数。

使用这些寄存器的程序必须使用FXSAVE和FXRSTR指令来保持和恢复状态。

但是在Pentium III对SSE的实现中,浮点数寄存器又一次被新的指令集占用了,但是这一次切换运算模式不是必要的了,只是SSE和浮点数指令不能同时进入CPU的处理线而已。

SSE2是Intel在P4的最初版本中引入的,但是AMD后来在Opteron 和Athlon 64中也加入了对它的支持。

这个指令集添加了对64位双精度浮点数的支持,以及对整型数据的支持,也就是说这个指令集中所有的MMX指令都是多余的了,同时也避免了占用浮点数寄存器。

这个指令集还增加了对CPU的缓存的控制指令。

AMD对它的扩展增加了8个XMM寄存器,但是需要切换到64位模式(AMD64)才可以使用这些寄存器。

Intel后来在其EM64T 架构中也增加了对AMD64的支持。

SSE3是Intel在P4的Prescott版中引入的指令集,AMD在Athlon 64的第五个版本中也添加了对它的支持。

这个指令集扩展的指令包含寄存器的局部位之间的运算,例如高位和低位之间的加减运算;浮点数到整数的转换,以及对超线程技术的支持。

SSE4指令集将给英特尔下一代平台带来“相当大的视频性能提升”。

sse2neon编译

sse2neon编译

sse2neon编译SSE2 (Streaming SIMD Extensions 2) 和 NEON 是两种在 x86 和 ARM 架构上常用的 SIMD (单指令多数据流) 指令集,它们可以显著提高多媒体和科学计算等应用的性能。

如果你想要将 SSE2 代码编译为 NEON 代码,这通常涉及到手动修改源代码或使用特定的编译器标志。

但请注意,并非所有的 SSE2 代码都可以或应该转换为 NEON,因为两者在功能和优化目标上有很大的不同。

以下是一些步骤和注意事项:1. 理解 SSE2 和 NEON 的差异:首先,你需要深入理解 SSE2 和 NEON 的工作原理和特性。

这包括它们的寄存器、操作码、数据类型以及它们在各种应用中的优势和限制。

2. 手动转换:对于一些简单的 SSE2 代码,你可能可以通过手工修改源代码来使用 NEON 指令。

但这通常需要深入的汇编知识和对两种指令集的深入理解。

3. 使用编译器标志:一些编译器提供了特定的标志来自动将 SSE2 代码转换为 NEON 代码。

例如,GCC 和 Clang 的 `-mfpmath=neon` 和 `-mfpu=neon` 标志可以用于生成 NEON 汇编。

但是,这些标志可能不会处理所有的 SSE2 代码,并且生成的代码可能不是最优的。

4. 测试和性能分析:无论你选择手动转换还是使用编译器标志,都需要进行充分的测试和性能分析,以确保转换后的代码在目标平台上运行得更快,并且没有引入错误或不稳定。

5. 考虑其他优化:除了将 SSE2 转换为 NEON,还有其他优化技术可以用于提高性能,例如使用更高效的算法、优化数据布局、减少内存访问等。

最后,如果你只是希望利用 NEON 的优势来加速你的代码,但并不想直接处理 SSE2 和 NEON 的差异,那么你可以考虑使用现有的库或框架,这些库或框架可能已经针对 NEON 进行了优化。

sse2指令使用注意事项

sse2指令使用注意事项

sse2指令使用注意事项嘿,各位小伙伴呀!今天咱们来唠唠《sse2指令使用注意事项》这事儿呢!哇,sse2指令可真是个很厉害的东西呀!但是在使用的时候,真的有不少需要注意的地方呢!首先呀,第一条注意事项呢,就是兼容性问题哦!哎呀呀,这个可太重要了呢!sse2指令虽然很强大,可是并不是所有的处理器都支持它的呀。

在你打算使用sse2指令之前呢,一定要先检查一下你的目标处理器是否兼容哦!不然的话,程序可能会出现各种奇奇怪怪的错误呢!这可就麻烦大了呀!你可不能想当然地就觉得所有的设备都能完美运行包含sse2指令的程序呀,对吧?第二条呢,就是数据类型的问题喽!哇,这个也不容小觑呀!sse2指令主要是针对特定的数据类型进行优化操作的呢。

比如说,它对单精度和双精度浮点数的处理就有自己的一套规则呀。

在使用的时候,你得特别小心数据类型的转换呢!如果数据类型转换不当,那结果可能就完全不是你想要的啦!这可怎么行呢?你肯定希望你的程序运行得准确无误吧!所以呀,一定要把数据类型的事儿搞清楚哦!再说说第三条注意事项吧。

嘿,这就是指令的顺序问题啦!sse2指令的执行顺序有时候会影响到最终的结果呢。

你不能随意地打乱指令的顺序呀!就好像搭积木一样,每一块积木都有它自己的位置,如果放错了位置,整个积木建筑可能就不稳定或者根本不是你想要的形状啦!同理,在使用sse2指令的时候,要按照正确的顺序来安排指令的执行,这样才能得到正确的结果呀!你要是不注意这个顺序,说不定就会被结果搞得一头雾水呢!还有呀,第四条要注意的是寄存器的使用呢!哇哦,寄存器在sse2指令的操作中扮演着非常关键的角色呢。

你要清楚地知道每个寄存器的功能和限制呀。

不能过度使用寄存器,也不能错误地使用寄存器来存储数据呢。

要是寄存器使用不当,可能会导致数据丢失或者计算错误哦!这可不是闹着玩的呢!哎呀呀,最后一点也很重要呢!那就是调试的时候要特别关注sse2指令相关的部分哦!当你的程序出现问题的时候,如果其中包含了sse2指令,那你可不能忽略这部分的调试呀。

SSE指令集入门

SSE指令集入门

SSE指令集⼊门Intel公司的单指令多数据流式扩展(SSE,Streaming SIMD Extensions)技术能够有效增强CPU浮点运算的能⼒。

Visual Studio .NET 2003提供了对SSE指令集的编程⽀持,从⽽允许⽤户在C++代码中不⽤编写汇编代码就可直接使⽤SSE指令的功能。

MSDN中有关SSE技术的主题[1]有可能会使不熟悉使⽤SSE汇编指令编程的初学者感到困惑,但是在阅读MSDN有关⽂档的同时,参考⼀下Intel软件说明书(Intel Software manuals)[2]会使你更清楚地理解使⽤SSE指令编程的要点。

SIMD(single-instruction, multiple-data)是⼀种使⽤单道指令处理多道数据流的CPU执⾏模式,即在⼀个CPU指令执⾏周期内⽤⼀道指令完成处理多个数据的操作。

考虑⼀下下⾯这个任务:计算⼀个很长的浮点型数组中每⼀个元素的平⽅根。

实现这个任务的算法可以这样写:for each f in array //对数组中的每⼀个元素f = sqrt(f) //计算它的平⽅根为了了解实现的细节,我们把上⾯的代码这样写:for each f in array{把f从内存加载到浮点寄存器计算平⽅根再把计算结果从寄存器中取出放⼊内存}具有Intel SSE指令集⽀持的处理器有8个128位的寄存器,每⼀个寄存器可以存放4个(32位)单精度的浮点数。

SSE同时提供了⼀个指令集,其中的指令可以允许把浮点数加载到这些128位的寄存器之中,这些数就可以在这些寄存器中进⾏算术逻辑运算,然后把结果放回内存。

采⽤SSE技术后,算法可以写成下⾯的样⼦:for each 4 members in array //对数组中的每4个元素{把数组中的这4个数加载到⼀个128位的SSE寄存器中在⼀个CPU指令执⾏周期中完成计算这4个数的平⽅根的操作把所得的4个结果取出写⼊内存}下⾯是⼀个演⽰的例⼦使⽤纯C++[cpp]1. void CSSETestDlg::ComputeArrayCPlusPlus(2. float* pArray1, // [in] first source array3. float* pArray2, // [in] second source array4. float* pResult, // [out] result array5. int nSize) // [in] size of all arrays6. {7.8. int i;9.10. float* pSource1 = pArray1;11. float* pSource2 = pArray2;12. float* pDest = pResult;13.14. for ( i = 0; i < nSize; i++ )15. {16. *pDest = (float)sqrt((*pSource1) * (*pSource1) + (*pSource2)17. * (*pSource2)) + 0.5f;18.19. pSource1++;20. pSource2++;21. pDest++;22. }23. }使⽤SSE内嵌原语[cpp]1. void CSSETestDlg::ComputeArrayCPlusPlusSSE(2. float* pArray1, // [in] first source array3. float* pArray2, // [in] second source array4. float* pResult, // [out] result array5. int nSize) // [in] size of all arrays6. {7. int nLoop = nSize/ 4;8.9. __m128 m1, m2, m3, m4;10.11. __m128* pSrc1 = (__m128*) pArray1;12. __m128* pSrc2 = (__m128*) pArray2;13. __m128* pDest = (__m128*) pResult;14.15.16. __m128 m0_5 = _mm_set_ps1(0.5f); // m0_5[0, 1, 2, 3] = 0.517.18. for ( int i = 0; i < nLoop; i++ )19. {20. m1 = _mm_mul_ps(*pSrc1, *pSrc1); // m1 = *pSrc1 * *pSrc121. m2 = _mm_mul_ps(*pSrc2, *pSrc2); // m2 = *pSrc2 * *pSrc222. m3 = _mm_add_ps(m1, m2); // m3 = m1 + m223. m4 = _mm_sqrt_ps(m3); // m4 = sqrt(m3)24. *pDest = _mm_add_ps(m4, m0_5); // *pDest = m4 + 0.525.26. pSrc1++;27. pSrc2++;28. pDest++;29. }30. }使⽤SSE汇编[cpp]1. void CSSETestDlg::ComputeArrayAssemblySSE(2. float* pArray1, // [输⼊] 源数组13. float* pArray2, // [输⼊] 源数组24. float* pResult, // [输出] ⽤来存放结果的数组5. int nSize) // [输⼊] 数组的⼤⼩6. {7. int nLoop = nSize/4;8. float f = 0.5f;9.10. _asm11. {12. movss xmm2, f // xmm2[0] = 0.513. shufps xmm2, xmm2, 0 // xmm2[1, 2, 3] = xmm2[0]14.15. mov esi, pArray1 // 输⼊的源数组1的地址送往esi16. mov edx, pArray2 // 输⼊的源数组2的地址送往edx17.18. mov edi, pResult // 输出结果数组的地址保存在edi19. mov ecx, nLoop //循环次数送往ecx20.21. start_loop:22. movaps xmm0, [esi] // xmm0 = [esi]23. mulps xmm0, xmm0 // xmm0 = xmm0 * xmm024.25. movaps xmm1, [edx] // xmm1 = [edx]26. mulps xmm1, xmm1 // xmm1 = xmm1 * xmm127.28. addps xmm0, xmm1 // xmm0 = xmm0 + xmm129. sqrtps xmm0, xmm0 // xmm0 = sqrt(xmm0)30.31. addps xmm0, xmm2 // xmm0 = xmm1 + xmm232.33. movaps [edi], xmm0 // [edi] = xmm034.35. add esi, 16 // esi += 1636. add edx, 16 // edx += 1637. add edi, 16 // edi += 1638.39. dec ecx // ecx--40. jnz start_loop //如果不为0则转向start_loop41. }42. }在信号处理中的实际应⽤(sse2):获得信号能量[cpp]1. /*2. * Compute Energy of a complex signal vector, removing the DC component!3. * input : points to vector4. * length : length of vector in complex samples5. */6.7. #define shift 48. #define shift_DC 09.10. int signal_energy(int *input, unsigned int length)11. {12. int i;13. int temp, temp2;14. register __m64 mm0, mm1, mm2, mm3;15. __m64 *in;16.17. in = (__m64 *)input;18.19. mm0 = _m_pxor(mm0,mm0);20. mm3 = _m_pxor(mm3,mm3);21.22. for (i = 0; i < length >> 1; i++) {23. mm1 = in[i];24. mm2 = mm1;25. mm1 = _m_pmaddwd(mm1, mm1);26. mm1 = _m_psradi(mm1, shift);27. mm0 = _m_paddd(mm0, mm1);28. mm2 = _m_psrawi(mm2, shift_DC);29. mm3 = _m_paddw(mm3, mm2);30. }31.32. mm1 = mm0;33. mm0 = _m_psrlqi(mm0, 32);34. mm0 = _m_paddd(mm0, mm1);35. temp = _m_to_int(mm0);36. temp /= length;37. temp <<= shift;38.39. /*now remove the DC component*/40. mm2 = _m_psrlqi(mm3, 32);41. mm2 = _m_paddw(mm2, mm3);42. mm2 = _m_pmaddwd(mm2, mm2);43. temp2 = _m_to_int(mm2);44. temp2 /= (length * length);45. temp2 <<= (2 * shift_DC);46. temp -= temp2;47. _mm_empty();48. _m_empty();49.50. return((temp > 0) ? temp : 1);51. }基于SSE指令集的程序设计简介实现的功能对应的SSE汇编指令VisualC++.NET中的SSE函数将4个32位浮点数放进⼀个128位的存储单元。

技术综述-SSE指令集的发展

技术综述-SSE指令集的发展

技术综述SSE指令集的发展学院(系):软件学院专业:网络工程学生姓名:梁博文学号:200992134 指导教师:王洁完成日期:2012-4-3大连理工大学Dalian University of Technology目录1.SSE指令集(SSE1).............................................................................................. I II1.1 什么是SSE指令集....................................................................................... I II1.2为什么引进SSE指令集 ........................................................................... I II1.2.1MMX指令集的局限性................................................................... I II1.2.2AMD推出的3DNow!指令集对Intel的MMX指令集带来的挑战III1.3SSE指令集的特点 .................................................................................... I V1.3.1SSE指令集的优点.......................................................................... I V1.3.2SSE指令集的局限性...................................................................... I V1.4SSE指令集内容简介 ................................................................................ I V1.4.1SSE指令集的指令个数.................................................................. I V1.4.2SSE指令集的寄存器 (V)1.4.3SSE指令简介 (V)2.SSE2指令集............................................................................................................. V I2.1什么是SSE2指令集 ............................................................................... V I2.2SSE2指令集的特点 ................................................................................ V I2.2.1SSE2指令集的优点........................................................................ V I2.2.2SSE2指令集的局限性.................................................................... V I2.3SSE2指令集简介 (VII)2.3.1SSE2指令集的指令个数 (VII)2.3.2SSE2指令集的寄存器 (VII)2.3.3SSE2指令简介 (VII)3.SSE3指令集.......................................................................................................... V III3.1SSE3指令集 ........................................................................................... V III3.1.1什么是SSE3指令集:................................................................ V III3.1.2SSE3指令集的目的:................................................................. V III3.1.3SSE3指令集简介:..................................................................... V III3.2SSSE3指令集............................................................................................ I X4.SSE4指令集 (X)4.1什么是SSE4指令集 (X)4.2SSE4指令集的特点 (X)4.3SSE4指令集内容 (X)4.3.1SSE4.1指令集内容 (X)4.3.2SSE4.2指令集内容 (XII)4.3.3SSE4指令集使用实例................................................................. X III5.总结........................................................................................................................ X IV1.SSE指令集(SSE1)1.1 什么是SSE指令集SSE指令集(Streaming SIMD Extensions,单指令多数据流扩展)是Intel在1999年推出的指令集,最初用于Pentium III处理器。

sse指令集 高低位交换

sse指令集 高低位交换

sse指令集高低位交换
SSE指令集是英特尔在Pentium 4处理器中推出的一组指令集,主要用于加速浮点运算。

SSE指令集支持数据的加载存储和算术运算,其中涉及到高低位交换的指令有:- 加载存储指令:
- LDDQU xmm, m128:从非对齐的内存地址中加载128位数到XMM寄存器。

- MOVDDUP xmm, xmm/m64:加载64bit数据到XMM寄存器的低64位,同时复制到其高64位。

- MOVSHDUP xmm, xmm/m128:只需复制第二与第四个32位元素从而把数据读入到接收寄存器中。

- MOVSLDUP xmm, xmm/m128:只需复制第一和第三个32位元素从而把数据读入到接收寄存器中。

- 算术指令:
- ADDSUBPD - (Add-Subtract-Packed-Double):双精度浮点高位加法,低位减法。

- ADDSUBPS - (Add-Subtract-Packed-Single):单精度浮点高位加法,低位减法。

这些指令可以提高数据处理的效率和速度,从而提高程序的性能。

在使用SSE指令集时,需要注意处理器的支持情况,并根据实际需求选择合适的指令。

SSE指令集

SSE指令集
private:
LARGE_INTEGER m_Frequency;
LARGE_INTEGER m_StartCount;
};
void ScaleValue1(float *pArray, DWORD dwCount, float fScale)
{
DWORD dwGroupCount = dwCount / 4;
t.Reset();
for (int i = 0; i < 100000; i++)
{
ScaleValue2(Array, ARRAYCOUNT, 1000.0f);
}
dTime = t.End();
cout << "Not Use SSE:" << dTime << "秒" << endl;
我是一个C++程序员,对汇编并不很熟,但我又想用SSE来优化我的程序,我该怎么做呢?幸好VC++.NET为我们提供了很方便的指令C函数级的封装和C格式数据类型,我们只需像平时写C++代码一样定义变量、调用函数就可以很好的应用SSE指令了。
当然了,我们需要包含一个头文件,这里面包括了我们需要的数据类型和函数的声明:
虽然SSE从理论上来讲要比传统的浮点运算会快,但是他所受的限制也很多,首先,虽然他执行一次相当于四次,会比传统的浮点运算执行4次的速度要快,但是他执行一次的速度却并没有想象中的那么快,所以要体现SSE的速度,必须有Stream做前提,就是大量的流数据,这样才能发挥SIMD的强大作用。其次,SSE支持的数据类型是4个32位(共计128位)浮点数集合,就是C、C++语言中的float[4],并且必须是以16位字节边界对齐的(稍后会以代码来进行阐释,关于边界对齐的概念,读者可以参考论坛上的其它文章,都会有很详细的解答,我这里就恕不赘述了)。因此这也给输入和输出带来了不少的麻烦,实际上主要影响SSE发挥性能的就是不停的对数据进行复制以适用应它的数据格式。

SSE指令集介绍

SSE指令集介绍

X86架构基本框架
指令集合 SSE3指令 SSE4指令 后续 SSE5指令 AVX指令 FMA指令
X86架构基本框架
寄存器 4个数据寄存器(EAX、EBX、ECX和EDX) 2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和 EBP) 6个段寄存器(ES、CS、SS、DS、FS和GS) 1个指令指针寄存器(EIP) 1个标志寄存器(EFlags)
// xmm0 = [esi] // xmm0 = xmm0 * xmm0 // xmm1 = [edx] // xmm1 = xmm1 * xmm1 // xmm0 = xmm0 + xmm1 // xmm0 = sqrt(xmm0) // xmm0 = xmm1 + xmm2 // [edi] = xmm0 // esi += 16 // edx += 16 // edi += 16 // ecx-//如果不为0则转向start_loop }}
SSE汇编指令:
SIMD优化
void CSSETestDlg::ComputeArrayAssemblySSE( float* pArray1, // [输入] 源数组1 float* pArray2, // [输入] 源数组2 float* pResult, // [输出] 用来存放结果的数组 int nSize) // [输入] 数组的大小 { int nLoop = nSize/4; float f = 0.5f; _asm { movss xmm2, f // xmm2[0] = 0.5 shufps xmm2, xmm2, 0 // xmm2[1, 2, 3] = xmm2[0] mov esi, pArray1 // 输入的源数组1的地址送往esi mov edx, pArray2 // 输入的源数组2的地址送往edx mov edi, pResult // 输出结果数组的地址保存在edi mov ecx, nLoop //循环次数送往ecx

流指令扩展指令集SSE解析

流指令扩展指令集SSE解析
从SSE4开始,AMD与Intel分道扬镳
1999年的时候,AMD在Athlon处理器上又添加了几个指令,这就是3DNow!+,又被称为3DNow!2。不过看到大势已去,AMD终于放弃了在多媒体指令集上的抵抗,转而支持Intel SSE,这样双方一直到SSE3都相安无事。统一的标准其实是一件好事,要是一个软件分别有SSE版本和3DNow!+版本,开发者和用户很快都会不堪其扰。
TMPGEnc支持完整的SSE指令
需要特别注意的是,每一代的指令集并不是互相替代的关系,而是互为补充的关系。并不是说这款软件支持SSE4.1,相比另一款采用MMX的软件,前者的效能就一定要高,或者前者作者的水平一定要高。连Intel也提醒开发者,请不要忽视MMX,因为它的速度在某些情况下比SSE更快。
流指令扩展指令集SSE艺的Intel Penryn处理器的发布(包括双核心桌面处理器Wolfdale、四核心桌面处理器Yorkfield、双核移动处理器Penryn等家族成员),一个新的名词又频繁地出现在我们眼前,这就是SSE4(Streaming SIMD Extensions,流指令扩展指令集),或者更准确的说法SSE4.1。我们已经习惯,每一代CPU的升级,Intel都要拿SSE说事,宣传得让局外人以为有了SSE,CPU就像吃了兴奋剂,没准还能跑过刘翔。下面我们就对SSE来一个大清算,让你有一个正确的了解。
那为什么Intel还要在x86指令集中再增加一组SSE指令呢?抱歉,这还得从SSE指令集的前身——MMX(Multi Media eXtension,多媒体扩展指令集)说起。正是从MMX开始,多媒体指令集才开始大红大紫。
MMX当年让不少人心甘情愿地掏银子
比如我们要计算从1到100这些数字它们的平方是多少。CPU会先把1从内存读入到寄存器,然后算出它的平方,再把计算结果从寄存器中取出放入内存中,然后不断重复这个过程直到把100个数字算完。但是问题是不管CPU的运算速度有多快,它一次也只能处理一个数据,在现实生活中,有很多数据特别是多媒体数据总是成组出现,比如图像,每一点的色彩就由红蓝绿三原色三个数据组成,声音也有左右声道之分。当CPU遇到这样数据,还需要拆开来挨个处理,效率无疑非常之低。

sse avx 汇编指令

sse avx 汇编指令

sse avx 汇编指令中括号"[ ]"是计算机科学中常用的符号,用于表示内存地址、数组索引和汇编指令等。

在本文中,我们将重点讨论SSE(流式SIMD扩展)和AVX(高级向量扩展)的汇编指令,了解它们的作用和使用方法。

SSE是英特尔公司推出的一种SIMD(单指令多数据)应用程序接口,用于优化多媒体和向量处理工作负载。

它引入了一组新的寄存器和指令,可以同时处理多个数据元素。

SSE指令集包含多个版本,如SSE2、SSE3、SSSE3等,每个版本都引入了新的功能和增强。

AVX是SSE指令集的扩展,以增加向量长度和操作数宽度为目标,进一步提升向量处理性能。

它引入了256位宽度的YMM寄存器和AVX指令,用于执行更大规模的数据处理任务。

AVX指令集在Sandy Bridge和后续英特尔处理器中得到支持。

现在让我们逐步了解如何使用SSE和AVX指令来进行向量计算和优化。

第一步:了解SSE和AVX寄存器SSE指令集引入了128位宽度的XMM寄存器,用于存储和处理向量数据。

每个寄存器可以同时存储和操作多个数据元素,例如四个32位整数或四个单精度浮点数。

AVX指令集引入了256位宽度的YMM寄存器,可以处理更大规模的向量数据。

第二步:学习SSE指令SSE指令的基本操作可以分为加载、存储、运算和其他辅助操作。

加载指令用于从内存中加载数据到XMM寄存器中,例如MOVAPS将128位的数据加载到XMM寄存器。

存储指令与之相反,用于将数据从寄存器存储到内存中。

运算指令用于执行各种数学和逻辑运算,例如ADDPS(加法运算)、MULPS(乘法运算)和CMPSS(比较运算)。

其他辅助操作指令用于数据移动、转换和交换等。

第三步:了解AVX指令AVX指令与SSE指令非常相似,但可以同时操作更大的向量数据。

例如,VMOVAPS可以一次性加载256位的数据到YMM寄存器中。

AVX还引入了一些新的指令和功能,如VPERMPS(向量重排)、VBLENDPS(向量混合)和VFMADDPS(向量乘加),用于更有效地执行向量计算和数据处理。

MMX及SSE指令集

MMX及SSE指令集
804852f: e2 fa 8048531: 5b 8048532: 5d 8048533: c3
mov %esp, %ebp push %ebx mov $0x14049d20, %ebx mov $0x400000, %ecx movdqa (%eax), %xmm0 movdqa (%ebx), %xmm1 paddb %xmm0, %xmm1
反映了体系结构发展的轨迹,字长不断扩充,指令保持兼容 ST(0)~ ST(7)是80位,MM0 ~MM7使用其低64位
SSE指令(SIMD操作)
用简单的例子来比较普通指令与数据级并行指令的执行速度
为使比较结果不受访存操作影响,下例中的运算操作数在寄存器中 为使比较结果尽量准确,例中设置的循环次数较大: 0x4000000=226 例子只是为了说明指令执行速度的快慢,并没有考虑结果是否溢出 以下是普通指令写的程序 080484f0 <dummy_add>: 80484f0: 55 push %ebp 所用时间约为22.643816s
SSE指令(SIMD操作)
以下是SIMD指令写的程序
08048510 <dummy_add_sse>: 22.643816s/ 1.411588s
8048516: 89 e5 8048518: 53 8048519: bb 20 9d 04 14 804851e: b9 00 00 40 00 8048523: 66 0f 6f 00 8048527: 66 0f 6f 0b 804852b: 66 0f fc c8
MMX及SSE指令Biblioteka MMX/SSE指令集的由来
• 由MMX发展而来的SSE架构
MMX指令使用8个64位寄存器MM0~MM7,借用8个80位寄存 器ST(0)~ST(7)中64位尾数所占的位,可同时处理8个字节,或4 个字,或2个双字,或一个64位的数据 MMX指令并没带来3D游戏性能的显著提升,故推出SSE指令, 并陆续推出SSE2、SSE3、SSSE3和SSE4等采用SIMD技术的指

SSE指令集发展历程回顾

SSE指令集发展历程回顾

SSE指令集发展历程回顾所谓SSE指令集也叫单指令多数据流扩展,最早是由英特尔提出,是为了加强浮点运算、图像处理等多媒体应用的能力,能更好的对整个系统进行控制,提高处理性能的指令的集合.而指令集的优秀与否,也关系到CPU的性能发挥,它也是CPU性能体现的一个严重标志.第一代的SSE指令集出现在PentiumIII处理器中包括了70条指令,其中包含提高3D图形运算效率的50条SIMD(单指令多数据技术)浮点运算指令、12条MMX整数运算增强指令、8条优化内存中持续数据块传输指令.理论上这些指令对目前流行的图像处理、浮点运算、3D运算、视频处理、音频处理等诸多多媒体应用起到全面强化的作用.SSE2指令集是Intel公司在SSE指令集的基础上发展起来的.相比于SSE,SSE2使用了144个新增指令,扩展了MMX技术和SSE技术,这些指令提高了广漠应用程序的运行性能.随MMX技术引进的SIMD整数指令从64位扩展到了128位,使SIMD整数类型操作的有用执行率成倍提高.双倍精度浮点SIMD指令允许以SIMD 格式同时执行两个浮点操作,提供双倍精度操作支持有助于加速财务、工程和科学应用.除SSE2指令之外,最初的SSE指令也得到增强,通过支持多种数据类型的算术运算,支持灵敏并且动态范围更广的计算功能.SSE2指令可让软件开发员极其灵敏的实施算法,并在运行诸如MPEG-2、MP3、3D图形等之类的软件时增强性能.SSE3指令是目前规模最小的指令集,它只有13条指令.它共划分为五个应运层,分别为数据传输命令、数据处理命令、分外处理命令、优化命令、超线程性能增强五个部分,其中超线程性能增强是一种全新的指令集,它可以提升处理器的超线程的处理能力,大大简化了超线程的数据处理过程,使处理器能够更加快速的进行并行数据处理.SSE4指令集是Conroe架构所引入的新指令集.这项原本计划应用于NetBurst 微架构Tejas核心处理器之上的全新技术也随着它的夭折最终没能实现,但是SSE4指令集出现在了Conroe上.SSE4指令集共包括16条指令,不过英特尔没有公布SSE4指令集的详尽资料.这相当令人感到纳闷.也许英特尔是基于分外的考虑,仅让少数合作软件厂商取得数据,只是这种作法实在很没有说服力就是了,天底下没有哪家处理器厂商,希望自己新增的指令越少人用越好.从SSE1到今年4月的SSE4都是由英特尔所提出,而AMD除了自己的指令集3DNow!以外,在其处理器中支持英特尔指令集的扩展大凡都是跟在英特尔后面的.而近几天,AMD率先公布了最新的SSE5指令集规格,而且宣布新技术将会在XXXX年以后的AMD新一代Bulldozer核心处理器上出现.AMD虽然有对应功能的指令集但名称均有所不同,而这次突然命名为SSE5,无疑是断了Intel的“后路”,双方是否会因此惹出争议甚至对簿公堂还很难说.SSE5是128-bit指令集,一共有170条指令,其中基础指令64条,新增的最严重的有两条:首先是“三操作数指令”(3-OperandInstructions).x86指令以往只能处理双操作数,而SSE5会提高到三操作数,达到RISC架构的水平,从而把多个简单的指令集整合到更高效的一个单独指令中,提高执行效率.然后是“熔合乘法累积”(FusedMultiplyAccumulate,FMACxx).该技术可以把乘法和其他算法结合起来,保证之用一条指令就能完成迭代运算,从而简化代码、提高效率,适用于真实图形着色、快速照相渲染、空间化音频、复向量(矢量)数学等场合.除此之外还有整数乘法累积指令(IMAC,IMADC)、置换与条件移动指令、向量比较与测试指令、精度控制舍入与变换指令等等.AMD表示,SSE5指令集的使命之一是增强高性能计算应用,并充分发挥多核心、多媒体的并行优势.SSE5将把以往只存在于高性能分外架构里的功能引入到x86平台中,以此化每条指令的输出能力,并增强代码库.在AMD巴塞罗那下周就要面世的前提下,竞争已经日趋激烈.不只在核心的数量和架构上,而是在包括指令集在内的任何技术层面,都已经开始对位的争夺,竞争已经开始细分化,任何一点点的疏忽和劣势都有可能左右市场的走向,让自己陷入晦气的境地.。

arm sve2 whilege 指令

arm sve2 whilege 指令

【文章】ARM SVE2 指令详解一、介绍ARM架构在处理器指令集方面一直以其精简高效而闻名,而ARM SVE2(Scalable Vector Extension 2)指令作为ARM最新的向量扩展技术,为处理向量数据提供了更强大的支持,进一步提高了处理器的性能和效率。

本文将深入探讨ARM SVE2 指令的原理、特点以及在实际应用中的优势。

二、ARM SVE2 指令的原理1. ARM SVE2 指令的特点ARM SVE2 指令在处理向量数据时采用了新的数据类型和指令集,主要包括了浮点和整数的向量运算指令,以及向量化的逻辑、算术、移位等操作。

与之前的SIMD指令集相比,ARM SVE2 指令可以支持更宽的寄存器,更多的操作数以及更加灵活的控制流程,极大地提高了向量计算的效率。

2. ARM SVE2 指令的实现原理ARM SVE2 指令通过矢量长度寄存器和向量位移寄存器来控制向量操作的长度和位移,这种灵活的方式可以根据实际需求来动态调整向量长度,实现了向量计算的高效灵活性。

ARM SVE2 指令还引入了紧凑的指令编码格式,使得更多的指令可以同时存储在指令缓存中,降低了指令访问延迟,提高了处理器的运行效率。

三、ARM SVE2 指令在实际应用中的优势1. 高性能计算ARM SVE2 指令在浮点计算和整数计算方面均有很大的优势,对于科学计算、图形处理、人工智能等领域的应用有着明显的性能提升。

由于ARM SVE2 指令支持更宽的寄存器,可以一次性处理更多的数据,从而加速了向量计算的速度,提高了处理器的并行运算能力。

2. 能耗效率ARM SVE2 指令在处理向量计算时能够更加高效地利用处理器资源,减少了数据传输和缓存访问的次数,降低了功耗消耗。

在移动设备、嵌入式系统等对功耗有严格要求的场景中,ARM SVE2 指令能够带来更加显著的能耗优势。

3. 应用广泛ARM SVE2 指令不仅适用于高性能计算领域,还可以在物联网、移动通信、嵌入式系统等各个领域得到广泛应用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

sse2指令集1移动指令:1. Movapsmovaps XMM,XMM/m128 movaps XMM/128,XMM把源存储器内容值送入目的寄存器,当有m128时,必须对齐内存16字节,也就是内存地址低4位为0.2. Movupsmovups XMM,XMM/m128 movaps XMM/128,XMM把源存储器内容值送入目的寄存器,但不必对齐内存16字节3. Movlpsmovlps XMM,m64把源存储器64位内容送入目的寄存器低64位,高64位不变,内存变量不必对齐内存16字节4. Movhpsmovhps XMM,m64把源存储器64位内容送入目的寄存器高64位,低64位不变,内存变量不必对齐内存16字节.5. Movhlpsmovhlps XMM,XMM把源寄存器高64位送入目的寄存器低64位,高64位不变.6. Movlhpsmovlhps XMM,XMM把源寄存器低64位送入目的寄存器高64位,低64位不变.7. movssmovss XMM,m32/XMM原操作数为m32时:dest[31-00] <== m32 dest[127-32] <== 0原操作数为XMM时: dest[31-00] <== src[31-00] dest[127-32]不变8. movmskpdmovmskpd r32,XMM取64位操作数符号位r32[0] <== XMM[63] r32[1] <== XMM[127] r32[31-2] <== 09. movmskpsmovmskps r32,XMM取32位操作数符号位r32[0] <== XMM[31] r32[1] <== XMM[63] r32[2] <== XMM[95] r32[3] <== XMM[127] r32[31-4] <== 010. pmovmskbpmovmskb 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] <== 011. movntpsmovntps m128,XMMm128 <== XMM 直接把XMM中的值送入m128,不经过cache,必须对齐16字节.12. Movntpdmovntpd m128,XMMm128 <== XMM 直接把XMM中的值送入m128,不经过cache,必须对齐16字节.13. Movntimovnti m32,r32m32 <== r32 把32寄存器的值送入m32,不经过cache.14. Movapdmovapd XMM,XMM/m128 movapd XMM/m128,XMM把源存储器内容值送入目的寄存器,当有m128时,必须对齐内存16字节15. Movupdmovupd XMM,XMM/m128 movapd XMM/m128,XMM把源存储器内容值送入目的寄存器,但不必对齐内存16字节.我感觉这两条指令同movaps 和movups 指令一样,不过又不确定.16. Movlpdmovlpd XMM,m64 movlpd m64,XMM把源存储器64位内容送入目的寄存器低64位,高64位不变,内存变量不必对齐内存16字节17. Movhpdmovhpd XMM,m64 movhpd m64,XMM把源存储器64位内容送入目的寄存器高64位,低64位不变,内存变量不必对齐内存16字节.18. Movdqamovdqa XMM,XMM/m128 movdqa XMM/m128,XMM把源存储器内容值送入目的寄存器,当有m128时,必须对齐内存16字节.19. Movdqumovdqu XMM,XMM/m128 movdqu XMM/m128,XMM把源存储器内容值送入目的寄存器,但不必对齐内存16字节.20. movq2dqmovq2dq XMM,MM把源寄存器内容送入目的寄存器的低64位,高64位清零.21. movdq2qmovdq2q MM,XMM把源寄存器低64位内容送入目的寄存器.22. Movdmovd XMM,r32/m32 movd MM,r32/m32把源存储器32位内容送入目的寄存器的低32位,高96位清零.movd r32/m32,XMM movd r32/m32,MM把源寄存器的低32位内容送入目的存储器32位.23. Movqmovq XMM,XMM/m64 movq MM,MM/m64把源存储器低64位内容送入目的寄存器的低64位,高64位清零.movq m64,XMM把源寄存器的低64位内容送入目的存储器.2 加法操作1. addpsaddps XMM,XMM/m128源存储器内容按双字对齐,共4个单精度浮点数与目的寄存器相加,结果送入目的寄存器,内存变量必须对齐内存16字节2. addsaddss XMM,XMM/m32源存储器的低32位1个单精度浮点数与目的寄存器的低32位1个单精度浮点数相加,结果送入目的寄存器的低32位高96位不变,内存变量不必对齐内存16字节3. addpdaddpd XMM,XMM/m128源存储器内容按四字对齐,共两个双精度浮点数与目的寄存器相加,结果送入目的寄存器,内存变量必须对齐内存16字节.4. addsdaddsd XMM,XMM/m64源存储器的低64位1个双精度浮点数与目的寄存器的低64位1个双精度浮点数相加,结果送入目的寄存器的低64位,高64位不变,内存变量不必对齐内存16字节5. padddpaddd XMM,XMM/m128把源存储器与目的寄存器按双字对齐无符号整数普通相加,结果送入目的寄存器,内存变量必须对齐内存16字节.6. Paddqpaddq XMM,XMM/m128把源存储器与目的寄存器按四字对齐无符号整数普通相加,结果送入目的寄存器,内存变量必须对齐内存16字节.7. Paddqpaddq MM,MM/m64把源存储器与目的寄存器四字无符号整数普通相加,结果送入目的寄存器.8. Pmaddwdpmaddwd 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*b79. Paddsbpaddsb XMM,XMM/m128 paddsb MM,MM/m64源存储器与目的寄存器按字节对齐有符号补码饱和相加,内存变量必须对齐内存16字节.10. paddswpaddsw XMM,XMM/m128源存储器与目的寄存器按字对齐有符号补码饱和相加,内存变量必须对齐内存16字节.11. paddusbpaddusb XMM,XMM/m128源存储器与目的寄存器按字节对齐无符号饱和相加,内存变量必须对齐内存16字节.12. Padduswpaddusw XMM,XMM/m128源存储器与目的寄存器按字对齐无符号饱和相加,内存变量必须对齐内存16字节.13. Paddbpaddb XMM,XMM/m128源存储器与目的寄存器按字节对齐无符号普通相加,内存变量必须对齐内存16字节.14. Paddwpaddw XMM,XMM/m128源存储器与目的寄存器按字对齐无符号普通相加,内存变量必须对齐内存16字节.15. Padddpaddd XMM,XMM/m128源存储器与目的寄存器按双字对齐无符号普通相加,内存变量必须对齐内存16字节.16. Paddqpaddq XMM,XMM/m128源存储器与目的寄存器按四字对齐无符号普通相加,内存变量必须对齐内存16字节.17.3 减法操作1. subpssubps XMM,XMM/m128源存储器内容按双字对齐,共4个单精度浮点数与目的寄存器相减(目的减去源),结果送入目的寄存器, 内存变量必须对齐内存16字节.2. Subsssubss XMM,XMM/m32源存储器的低32位1个单精度浮点数与目的寄存器的低32位1个单精度浮点数相减(目的减去源), 结果送入目的寄存器的低32位,高96位不变,内存变量不必对齐内存16字节3. Subpdsubpd XMM,XMM/m128把目的寄存器内容按四字对齐,两个双精度浮点数,减去源存储器两个双精度浮点数, 结果送入目的寄存器,内存变量必须对齐内存16字节.4. subsdsubsd XMM,XMM/m128把目的寄存器的低64位1个双精度浮点数,减去源存储器低64位1个双精度浮点数,结果送入目的寄存器的低64位,高64位不变,内存变量不必对齐内存16字节5. Psubdpsubd XMM,XMM/m128把目的寄存器与源存储器按双字对齐无符号整数普通相减,结果送入目的寄存器, 内存变量必须对齐内存16字节.(目的减去源)6. Psubqpsubq XMM,XMM/m128把目的寄存器与源存储器按四字对齐无符号整数普通相减,结果送入目的寄存器, 内存变量必须对齐内存16字节.(目的减去源)7. Psubqpsubq MM,MM/m64把目的寄存器与源存储器四字无符号整数普通相减,结果送入目的寄存器.(目的减去源)8. psubsbpsubsb XMM,XMM/m128源存储器与目的寄存器按字节对齐有符号补码饱和相减(目的减去源),内存变量必须对齐内存16字节.9. Psubswpsubsw XMM,XMM/m128源存储器与目的寄存器按字对齐有符号补码饱和相减(目的减去源),内存变量必须对齐内存16字节.10. Psubusbpsubusb XMM,XMM/m128源存储器与目的寄存器按字节对齐无符号饱和相减(目的减去源),内存变量必须对齐内存16字节.11. Psubuswpsubusw XMM,XMM/m128源存储器与目的寄存器按字对齐无符号饱和相减(目的减去源),内存变量必须对齐内存16字节.12. psubbpsubb XMM,XMM/m128源存储器与目的寄存器按字节对齐无符号普通相减(目的减去源),内存变量必须对齐内存16字节.13. Psubwpsubw XMM,XMM/m128源存储器与目的寄存器按字对齐无符号普通相减(目的减去源),内存变量必须对齐内存16字节.14. Psubdpsubd XMM,XMM/m128源存储器与目的寄存器按双字对齐无符号普通相减(目的减去源),内存变量必须对齐内存16字节.15. Psubqpsubq XMM,XMM/m128源存储器与目的寄存器按四字对齐无符号普通相减(目的减去源),内存变量必须对齐内存16字节.16.4 比较操作1. Maxpsmaxps XMM,XMM/m128源存储器4个单精度浮点数与目的寄存器4个单精度浮点数比较,较大数放入对应目的寄存器,内存变量必须对齐内存16字节.2. Maxssmaxss XMM,XMM/m32源存储器低32位1个单精度浮点数与目的寄存器低32位1个单精度浮点数比较,较大数放入目的寄存器低32位,高96位不变内存变量不必对齐内存16字节3. Minpsminps XMM,XMM/m128源存储器4个单精度浮点数与目的寄存器4个单精度浮点数比较,较小数放入对应目的寄存器,内存变量必须对齐内存16字节.4. minssminss XMM,XMM/m32源存储器低32位1个单精度浮点数与目的寄存器低32位1个单精度浮点数比较,较小数放入目的寄存器低32位,高96位不变内存变量不必对齐内存16字节5. cmppscmpps XMM0,XMM1,imm8 imm8是立即数范围是0~7根据imm8的值进行4对单精度浮点数的比较,符合imm8的就置目的寄存器对应的32位全1,否则全0当imm8 = 0时,目的寄存器等于原寄存器数时,置目的寄存器对应的32位全1,否则全0imm8 = 1 时,目的寄存器小于原寄存器数时,置目的寄存器对应的32位全1,否则全0imm8 = 2 时,目的寄存器小于等于原寄存器数时,置目的寄存器对应的32位全1,否则全0 imm8 = 4 时,目的寄存器不等于原寄存器数时,置目的寄存器对应的32位全1,否则全0 imm8 = 5 时,目的寄存器大于等于原寄存器数时,置目的寄存器对应的32位全1,否则全0 imm8 = 6 时,目的寄存器大于原寄存器数时,置目的寄存器对应的32位全1,否则全06. pcmpeqbpcmpeqb XMM,XMM/m128目的寄存器与源存储器按字节比较,如果对应字节相等,就置目的寄存器对应字节为0ffh,否则为00h内存变量必须对齐内存16字节.7. Pcmpeqwpcmpeqw XMM,XMM/m128目的寄存器与源存储器按字比较,如果对应字相等,就置目的寄存器对应字为0ffffh,否则为0000h, 内存变量必须对齐内存16字节8. Pcmpeqdpcmpeqd XMM,XMM/m128目的寄存器与源存储器按双字比较,如果对应双字相等,就置目的寄存器对应双字为0ffffffffh,否则为00000000h内存变量必须对齐内存16字节9. Pcmpgtbpcmpgtb XMM,XMM/m128目的寄存器与源存储器按字节(有符号补码)比较,如果目的寄存器对应字节大于源存储器,就置目的寄存器对应字节为0ffh, 否则为00h,内存变量必须对齐内存16字节10. Pcmpgtwpcmpgtw XMM,XMM/m128目的寄存器与源存储器按字(有符号补码)比较,如果目的寄存器对应字大于源存储器,就置目的寄存器对应字为0ffffh, 否则为0000h,内存变量必须对齐内存16字节.11. Pcmpgtdpcmpgtd XMM,XMM/m128目的寄存器与源存储器按双字(有符号补码)比较,如果目的寄存器对应双字大于源存储器, 就置目的寄存器对应双字为0ffffffffh,否则为00000000h,内存变量必须对齐内存16字节.5 计算操作1. rcppsrcpps XMM,XMM/m128源存储器4个单精度浮点数的倒数放入对应目的寄存器,内存变量必须对齐内存16字节注:比如2.0E0的倒数为1÷2.0E0 = 5.0E-1, 这操作只有12bit的精度2. rcpssrcpss XMM,XMM/32源存储器低32位1个单精度浮点数的倒数放入目的寄存器低32位,高96位不变3. rsqrtpsrsqrtps XMM,XMM/m128源存储器4个单精度浮点数的开方的倒数放入对应目的寄存器,内存变量必须对齐内存16字节. 比如2.0E0的开方的倒数为1÷√2.0E0≈ 7.0711E-1, 这操作只有12bit的精度. 4. Rsqrtssrsqrtss XMM,XMM/32源存储器低32位1个单精度浮点数的开方的倒数放入目的寄存器低32位,高96位不变,内存变量不必对齐内存16字节.5. Pavgbpavgb MM,MM/m64 pavgb XMM,XMM/m128把源存储器与目的寄存器按字节无符号整数相加,再除以2,结果四舍五入为整数放入目的寄存器, 源存储器为m128时,内存变量必须对齐内存16字节. 注:此运算不会产生溢出.6. Pavgwpavgw MM,MM/m64 pavgw XMM,XMM/m128把源存储器与目的寄存器按字无符号整数相加,再除以2,结果四舍五入为整数放入目的寄存器, 源存储器为m128时,内存变量必须对齐内存16字节.7. Sqrtpdsqrtpd XMM,XMM/m128源存储器两个双精度浮点数的开方放入对应目的寄存器,内存变量必须对齐内存16字节.8. Sqrtsdsqrtsd XMM,XMM/m128源存储器低64位1个双精度浮点数的开方放入目的寄存器低64位,高64位不变,内存变量不必对齐内存16字节6 乘法操作1. Mulpsmulps XMM,XMM/m128源存储器内容按双字对齐,共4个单精度浮点数与目的寄存器相乘,结果送入目的寄存器,内存变量必须对齐内存16字节.2. Mulssmulss XMM,XMM/32源存储器的低32位1个单精度浮点数与目的寄存器的低32位1个单精度浮点数相乘,结果送入目的寄存器的低32位,高96位不变,内存变量不必对齐内存16字节3. Mulpdmulpd XMM,XMM/m128源存储器内容按四字对齐,共两个双精度浮点数与目的寄存器相乘,结果送入目的寄存器,内存变量必须对齐内存16字节4. Mulsdmulsd XMM,XMM/m128源存储器的低64位1个双精度浮点数与目的寄存器的低64位1个双精度浮点数相乘,结果送入目的寄存器的低64位,高64位不变,内存变量不必对齐内存16字节5. Pmuludqpmuludq XMM,XMM/m128把源存储器与目的寄存器的低32位无符号整数相乘,结果变为64位,送入目的寄存器低64位, 把源存储器与目的寄存器的高64位的低32位无符号整数相乘,结果变为64位,送入目的寄存器高64位内存变量必须对齐内存16字节.高64位| 低64位目的寄存器: a0 | a1 | a2 | a3源存储器: b0 | b1 | b2 | b3目的寄存器结果: b1*a1 | b3*a36. Pmuludqpmuludq MM,MM/m64把源存储器与目的寄存器的低32位无符号整数相乘,结果变为64位,送入目的寄存器.7. pmulhwpmulhw XMM,XMM/m128源存储器与目的寄存器按字对齐有符号补码饱和相乘,取结果的高16位放入目的寄存器对应字中. 内存变量必须对齐内存16字节8. pmullwpmullw XMM,XMM/m128源存储器与目的寄存器按字对齐有符号补码饱和相乘,取结果的低16位放入目的寄存器对应字中. 内存变量必须对齐内存16字节.9.7 除法操作1. Divpsdivps XMM,XMM/m128目的寄存器共4个单精度浮点数除以源存储器4个单精度浮点数,结果送入目的寄存器,内存变量必须对齐内存16字节.2. Divssdivss XMM,XMM/32目的寄存器低32位1个单精度浮点数除以源存储器低32位1个单精度浮点数,结果送入目的寄存器的低32位,高96位不变,内存变量不必对齐内存16字节3. Divpddivpd XMM,XMM/m128目的寄存器共两个双精度浮点数除以源存储器两个双精度浮点数,结果送入目的寄存器,内存变量必须对齐内存16字节4. Divsddivsd XMM,XMM/m128目的寄存器低64位1个双精度浮点数除以源存储器低64位1个双精度浮点数,结果送入目的寄存器的低64位,高64位不变,内存变量不必对齐内存16字节.8 位操作1. Andpsandps XMM,XMM/m128源存储器128个二进制位'与'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.2. Orpsorps XMM,XMM/m128源存储器128个二进制位'或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.3. Xorpsxorps XMM,XMM/m128源存储器128个二进制位'异或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.4. Unpckhpsunpckhps XMM,XMM/m128源存储器与目的寄存器高64位按双字交错排列,结果送入目的寄存器,内存变量必须对齐内存16字节.高64位| 低64位 目的寄存器: a0 | a1 | a2 | a3 源存储器: b0 | b1 | b2 | b3 目的寄存器结果: b0 | a0 | b1 | a15. Unpcklpsunpcklps XMM,XMM/m128源存储器与目的寄存器低64位按双字交错排列,结果送入目的寄存器,内存变量必须对齐内存16字节高64位| 低64位目的寄存器: a0 | a1 | a2 | a3 源存储器: b0 | b1 | b2 | b3 目的寄存器结果: b2 | a2 | b3 | a36. Pextrwpextrw 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 87. Pinsrwpinsrw 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 88. Pmaxswpmaxsw MM,MM/m64 pmaxsw XMM,XMM/m128把源存储器与目的寄存器按字有符号(补码)整数比较,大数放入目的寄存器对应字, 源存储器为m128时,内存变量必须对齐内存16字节9. Pmaxubpmaxub MM,MM/m64 pmaxsw XMM,XMM/m128把源存储器与目的寄存器按字节无符号整数比较,大数放入目的寄存器对应字节, 源存储器为m128时,内存变量必须对齐内存16字节.10. pminswpminsw MM,MM/m64 pmaxsw XMM,XMM/m128把源存储器与目的寄存器按字有符号(补码)整数比较,较小数放入目的寄存器对应字, 源存储器为m128时,内存变量必须对齐内存16字节.11. Pminubpminub MM,MM/m64 pmaxsw XMM,XMM/m128把源存储器与目的寄存器按字节无符号整数比较,较小数放入目的寄存器对应字节, 源存储器为m128时,内存变量必须对齐内存16字节12. Maxpdmaxpd XMM,XMM/m128源存储器两个双精度浮点数与目的寄存器两个双精度浮点数比较,较大数放入对应目的寄存器,内存变量必须对齐内存16字节.13. Maxsdmaxsd XMM,XMM/m128源存储器低64位1个双精度浮点数与目的寄存器低64位1个双精度浮点数比较,较大数放入目的寄存器低64位,高64位不变内存变量不必对齐内存16字节.14. Minpdminpd XMM,XMM/m128源存储器两个双精度浮点数与目的寄存器两个双精度浮点数比较,较小数放入对应目的寄存器,内存变量必须对齐内存16字节.15. Minsdminsd XMM,XMM/m128源存储器低64位1个双精度浮点数与目的寄存器低64位1个双精度浮点数比较,较小数放入目的寄存器低64位,高64位不变内存变量不必对齐内存16字节.16. Andpdandpd XMM,XMM/m128源存储器128个二进制位'与'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.17. Andnpdandnpd XMM,XMM/m128目的寄存器128个二进制位先取'非',再'与'源存储器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节18. Orpdorpd XMM,XMM/m128源存储器128个二进制位'或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.19. Xorpdxorpd XMM,XMM/m128源存储器128个二进制位'异或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.20. Pslldqpslldq XMM,imm8把目的寄存器128位按imm8(立即数)指定字节数逻辑左移,移出的字节丢失.imm8 == 1时,代表左移8位,imm8 == 2时,代表左移16位.21. Psrldqpsrldq XMM,imm8把目的寄存器128位按imm8(立即数)指定字节数逻辑右移,移出的字节丢失.imm8 == 1时,代表右移8位,imm8 == 2时,代表右移16位.22. Psllwpsllw XMM,XMM/m128 psllw XMM,imm8把目的寄存器按字由源存储器(或imm8 立即数)指定位数逻辑左移,移出的位丢失. 低字移出的位不会移入高字,内存变量必须对齐内存16字节.23. Psrlwpsrlw XMM,XMM/m128 psrlw XMM,imm8把目的寄存器按字由源存储器(或imm8 立即数)指定位数逻辑右移,移出的位丢失.高字移出的位不会移入低字,内存变量必须对齐内存16字节.24. Pslldpslld XMM,XMM/m128 pslld XMM,XMM imm8把目的寄存器按双字由源存储器(或imm8 立即数)指定位数逻辑左移,移出的位丢失. 低双字移出的位不会移入高双字,内存变量必须对齐内存16字节.25. Psrldpsrld XMM,XMM/m128 psrld XMM,imm8把目的寄存器按双字由源存储器(或imm8 立即数)指定位数逻辑右移,移出的位丢失.高双字移出的位不会移入低双字,内存变量必须对齐内存16字节.pandpand XMM,XMM/m128源存储器128个二进制位'与'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节. 我发现与andpd功能差不多,就不知其它特性是否一样26. Pandnpandn XMM,XMM/m128目的寄存器128个二进制位先取'非',再'与'源存储器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节27. Porpor XMM,XMM/m128源存储器128个二进制位'或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.28. Pxorpxor XMM,XMM/m128源存储器128个二进制位'异或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节.29. packuswbpackuswb 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| a730. packsswbpacksswb 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| a731. packssdwpackssdw 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 | a332. punpckldqpunpckldq XMM,XMM/m128把源存储器与目的寄存器低64位按双字交错排列,内存变量必须对齐内存16字节.高64位| 低64位目的寄存器: a0 | a1 | a2 | a3源寄存器: b0 | b1 | b2 | b3目的寄存器排列结果: b2 | a2 | b3 | a333. punpckhdq把源存储器与目的寄存器高64位按双字交错排列,内存变量必须对齐内存16字节.高64位| 低64位目的寄存器: a0 | a1 | a2 | a3源寄存器: b0 | b1 | b2 | b3目的寄存器排列结果: b0 | a0 | b1 | a134. 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 | a735. punpckhwdpunpckhwd 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 | a336. punpcklbwpunpcklbw 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| aF37. 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| a738. shufpsshufps 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 h39. shufpdshufpd 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 hXMM1 = 5555555566666666 aaaaaaaacccccccc h,执行shufpd XMM0,XMM1,101001 1 0 b则XMM0 = 5555555566666666 3333333344444444 h40. pshuflwpshuflw 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 hXMM1 = 5555555566666666 7777 8888 9999 cccc h,执行pshuflw XMM0,XMM1,10 10 01 10 b 则XMM0 = 5555555566666666 8888 8888 9999 8888 h41. pshufhwpshufhw 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 hXMM1 = 7777 8888 9999 cccc 5555555566666666 h,执行pshufhw XMM0,XMM1,10 10 01 10 b 则XMM0 = 8888 8888 9999 8888 5555555566666666 h42. pshufdpshufd 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 h9 数据类型操作43. cvtpi2pscvtpi2ps XMM,MM/m64源存储器64位两个32位有符号(补码)整数转为两个单精度浮点数,放入目的寄存器低64中,高64位不变.44. cvtsi2sscvtsi2ss XMM,r32/m32源存储器1个32位有符号(补码)整数转为1个单精度浮点数,放入目的寄存器低32中,高96位不变.45. cvtps2picvtps2pi MM,XMM/m64把源存储器低64位两个32位单精度浮点数转为两个32位有符号(补码)整数,放入目的寄存器46. cvttps2picvttps2pi MM,XMM/m64类似于cvtps2pi,截断取整.47. cvtss2sicvtss2si r32,XMM/m32把源存储器低32位1个单精度浮点数转为1个32位有符号(补码)整数,放入目的寄存器. 48. cvttss2sicvttss2si r32,XMM/m32类似cvtss2si,截断取整.49. cvtps2pdcvtps2pd XMM,XMM/m64把源存储器低64位两个单精度浮点数变成两个双精度浮点数,结果送入目的寄存器.50. cvtss2sdcvtss2sd XMM,XMM/m32把源存储器低32位1个单精度浮点数变成1个双精度浮点数,结果送入目的寄存器的低64位,高64位不变.51. cvtpd2ps把源存储器两个双精度浮点数变成两个单精度浮点数,结果送入目的寄存器的低64位,高64位清零, 内存变量必须对齐内存16字节.^特殊状态^3.14E5 (表示负无穷大)52. cvtsd2sscvtsd2ss XMM,XMM/m64把源存储器低64位1个双精度浮点数变成1个单精度浮点数,结果送入目的寄存器的低32位,高96位不变.53. cvtpd2picvtpd2pi MM,XMM/m128把源存储器两个双精度浮点数变成两个双字有符号整数,结果送入目的寄存器,内存变量必须对齐内存16字节. 如果结果大于所能表示的范围,那么转化为80000000h(正数也转为此值).。

相关文档
最新文档