本文主要是介绍MMX指令集(详解),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
转自 http://blog.csdn.net/dahan_wangtao/article/details/1944153
EMMS | MMX状态置空: 将FP特征字置空(全1),使后续浮点指令可以使用浮点寄存器,其他MMX指令自动置FP为全0.本指令应在所有MMX例程结束和调用可含有FP指令的例程时使用,以清除MMX状态. | |||||||||||||||||||||||||
MOVD mm,r/m32 MOVD r/m32,mm | 转移32位数据: 将32位数据从整型寄存器/内存移到MMX寄存器,和反向移动.MOVD不能在MMX寄存器之间,内存之间及整型寄存器之间移动数据.目标操作数为MMX寄存器时,32位源操作数写入目标寄存器的低32位.目标寄存器"0扩展"为64位.源操作数为MMX寄存器时,该寄存器的低32位被写入目标操作数. | |||||||||||||||||||||||||
MOVQ mm,r/m64 MOVQ r.m64,mm | 转移64位数据: 将64位数据从整型寄存器/内存移到MMX寄存器,和反向移动.目标操作数和源操作数可为MMX寄存器,64位内存操作数.但MOVQ不能在内存和内存之间进行数据转移. | |||||||||||||||||||||||||
PACKSSWB mm,mm/m64 | 有符号饱和方式数据成组: 将MMX寄存器和MMX寄存器/内存单元中的有符号字组变成MMX寄存器的有符号字节组.和将MMX寄存器和MMX寄存器/内存单元中的有符号双字组变成MMX寄存器的有符号字组.(注1) | |||||||||||||||||||||||||
PACKUSWB mm,mm/m64 | 无符号饱和方式数据成组 将MMX寄存器和MMX寄存器/内存单元中的有符号字组变成MMX寄存器的无符号字节组.(注1) | |||||||||||||||||||||||||
PADDB mm,mm/m64 | 环绕方式数据组相加: 按环绕方式将MMX寄存器/内存单元中的字节组(字组,双字组)相加到MMX寄存器中(注1) | |||||||||||||||||||||||||
PADDSB mm,mm/m64 | 饱和方式有符号数据组相加: 按饱和方式将MMX寄存器/内存单元中的有符号字节组(字组)相加到MMX寄存器中的有符号字节组(字组)数据.(注1) | |||||||||||||||||||||||||
PADDUSB mm,mm/m64 | 饱和方式无符号数据组相加: 按饱和方式将MMX寄存器/内存单元中的无符号字节组(字组)相加到MMX寄存器中的无符号字节组(字组)数据.(注1) | |||||||||||||||||||||||||
PAND mm,mm/m64 | 逐位逻辑与: 将MMX寄存器/内存单元中的64位数据进行与操作,结果存于MMX寄存器中. | |||||||||||||||||||||||||
PANDN mm,mm/m64 | 逐位逻辑与非: 将MMX寄存器中的64位值取反,再将取反后的MMX寄存器与MMX寄存器/内存单元中的64位数据进行与操作,结果存于MMX寄存器中. | |||||||||||||||||||||||||
PCMPEQB mm,mm/m64 | 成组数据的相等比较: 将MMX寄存器与MMX寄存器/内存单元中的字节组(字组,双字组)数据进行相等比较. 该指令将目标操作数和源操作数的相应数据元素进行比较,相等则目标寄存器的对应数据元素被置为全1,否则置为全0. eg:PCMPEQE mm,mm/m64
| |||||||||||||||||||||||||
PCMPGTB mm,mm/m64 | 成组数据的相等比较: 将MMX寄存器与MMX寄存器/内存单元中的字节组(字组,双字组)数据进行大于比较. 该指令将目标操作数和源操作数的相应数据元素进行比较,大于则目标寄存器的对应数据元素被置为全1,否则置为全0.(参考上一条) | |||||||||||||||||||||||||
PMADDWD mm,mm/m64 | 数据组(字组)的乘加: 将MMX寄存器与MMX寄存器/内存单元中的字组数据相乘,然后将32位结果逐对相加并作为双字存于MMX寄存器中. eg:PMADDWD mm,mm/m64
| |||||||||||||||||||||||||
PMULHW mm,mm/m64 | 成组数据(字组)的乘后取高位: 将MMX寄存器与MMX寄存器/内存单元中的有符号字组数据相乘,然后将结果的高16位存入MMX寄存器. eg:PMULHW mm,mm/m64
| |||||||||||||||||||||||||
PMULLW mm,mm/m64 | 成组数据(字组)的乘后取低位: 将MMX寄存器与MMX寄存器/内存单元中的有符号字组数据相乘,然后将结果的低16位存入MMX寄存器.(参考上一条) | |||||||||||||||||||||||||
POR mm,mm/m64 | 逐位逻辑或: 将MMX寄存器/内存单元中的64位数据进行或操作,结果存于MMX寄存器中. | |||||||||||||||||||||||||
PSLLW mm,mm/m64 | 成组数据的逻辑左移: 将MMX寄存器中的字(双字,四字)数据按MMX寄存器/内存单元指定的个数左移,低位移入0. 将MMX寄存器中的字(双字,四字)数据按8位立即数指定的个数左移,低位移入0. | |||||||||||||||||||||||||
PSRAW mm,mm/m64 PSRAD mm,mm/m64 PSRAW mm,imm8 PSRAD mm,imm8 | 成组数据的算术右移: 将MMX寄存器中的字(双字)数据按MMX寄存器/内存单元指定的个数右移,移动中保持符号位. 将MMX寄存器中的字(双字)数据按8位立即数指定的个数右移,移动中保持符号位. | |||||||||||||||||||||||||
PSRLW mm,mm/m64 PSRLD mm,mm/m64 PSRLQ mm,mm/m64 PSRLW mm,imm8 PSRLD mm,imm8 PSRLQ mm,imm8 | 成组数据的逻辑右移: 将MMX寄存器中的字(双字)数据按MMX寄存器/内存单元指定的个数右移,移出位用0填充. 将MMX寄存器中的字(双字)数据按8位立即数指定的个数右移,移出位用0填充. | |||||||||||||||||||||||||
PSUBB mm,mm/m64 PSUBW mm,mm/m64 PSUBD mm,mm/m64 | 环绕方式成组数据相减: 从MMX寄存器中按字节(字,双字)减去MMX寄存器/内存单元中的字节(字,双字)组.(注1) | |||||||||||||||||||||||||
PSUBSB mm,mm/m64 | 饱和方式有符号成组数据相减: 从MMX寄存器中的有符号成组字节(字)组数据减去MMX寄存器/内存单元中的有符号字节(字)组数据.(注1) | |||||||||||||||||||||||||
PSUBUSB mm,mm/m64 PSUBUSW mm,mm/m64 | 饱和方式有符号成组数据相减: 从MMX寄存器中的无符号成组字节(字)组数据减去MMX寄存器/内存单元中的无符号字节(字)组数据.(注1) | |||||||||||||||||||||||||
PUNPCKHBW mm,mm/m64 PUNPCKHWD mm,mm/m64 PUNPCKHDQ mm,mm/m64 | 高位成组数据分解: 此指令交替取出源操作数和目标操作数的数据元素的高半部分,写入目标操作数中,数据元素的低半部分被忽略. eg:PUNPCKHBW mm,mm/m64 ![]() | |||||||||||||||||||||||||
PUNPCKLBW mm,mm/m64 PUNPCKLWD mm,mm/m64 PUNPCKLDQ mm,mm/m64 | 低位成组数据分解: 此指令交替取出源操作数和目标操作数的数据元素的低半部分,写入目标操作数中,数据元素的高半部分被忽略.(参考上一条) | |||||||||||||||||||||||||
PXOR mm,mm/m64 | 逐位逻辑异或: 将MMX寄存器/内存单元中的64位数据进行异或操作,结果存于MMX寄存器中. |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
补充:
PMULHUW - 压缩无符号乘法取高位
操作码 | 指令 | 说明 |
0F E4 /r | PMULHUW mm1, mm2/m64 | 将 mm1 寄存器与 mm2/m64 中的压缩无符号字整数相乘,并将结果的高 16 位存储到 mm1。 |
66 0F E4 /r | PMULHUW xmm1, xmm2/m128 | 将 xmm1 与 xmm2/m128 中的压缩无符号字整数相乘,并将结果的高 16 位存储到 xmm1。 |
说明
对目标操作数(第一个操作数)与源操作数(第二个操作数)中的压缩无符号字整数执行 SIMD 乘法,并将每个 32 位中间结果的高 16 位存储到目标操作数。(图 3-7 显示使用 64 位操作数时此操作的情况)。源操作数可以是 MMX™ 技术寄存器或 64 位内存位置,也可以是 XMM 寄存器或 128 位内存位置。目标操作数可以是 MMX 或 XMM 寄存器。
|
PMULHUW 与 PMULHW 指令操作
操作
PMULHUW instruction with 64-bit operands:
TEMP0[31-0] DEST[15-0] * SRC[15-0]; * Unsigned multiplication *
TEMP1[31-0] DEST[31-16] * SRC[31-16];
TEMP2[31-0] DEST[47-32] * SRC[47-32];
TEMP3[31-0] DEST[63-48] * SRC[63-48];
DEST[15-0] TEMP0[31-16];
DEST[31-16] TEMP1[31-16];
DEST[47-32] TEMP2[31-16];
DEST[63-48] TEMP3[31-16];
PMULHUW instruction with 128-bit operands:
TEMP0[31-0] DEST[15-0] * SRC[15-0]; * Unsigned multiplication *
TEMP1[31-0] DEST[31-16] * SRC[31-16];
TEMP2[31-0] DEST[47-32] * SRC[47-32];
TEMP3[31-0] DEST[63-48] * SRC[63-48];
TEMP4[31-0] DEST[79-64] * SRC[79-64];
TEMP5[31-0] DEST[95-80] * SRC[95-80];
TEMP6[31-0] DEST[111-96] * SRC[111-96];
TEMP7[31-0] DEST[127-112] * SRC[127-112];
DEST[15-0] TEMP0[31-16];
DEST[31-16] TEMP1[31-16];
DEST[47-32] TEMP2[31-16];
DEST[63-48] TEMP3[31-16];
DEST[79-64] TEMP4[31-16];
DEST[95-80] TEMP5[31-16];
DEST[111-96] TEMP6[31-16];
DEST[127-112] TEMP7[31-16];
英特尔(R) C++ 编译器等价内部函数
PMULHUW __m64 _mm_mulhi_pu16(__m64 a, __m64 b)
PMULHUW __m128i _mm_mulhi_epu16 ( __m128i a, __m128i b)
影响的标志
无。
保护模式异常
#GP(0) - 如果内存操作数有效地址超出 CS、DS、ES、FS 或 GS 段限制。(仅限 128 位操作)。如果内存操作数未对齐 16 字节边界,不论是哪一段。
#SS(0) - 如果内存操作数有效地址超出 SS 段限制。
#UD - 如果 CR0 中的 EM 设置为 1。(仅限 128 位操作)。如果 CR4 中的 OSFXSR 是 0。(仅限 128 位操作)。如果 CPUID 功能标志 SSE-2 为 0。
#NM - 如果 CR0 中的 TS 设置为 1。
#MF(仅限 64 位操作)- 如果存在未决的 x87 FPU 异常。
#PF(错误代码) - 如果发生页错误。
#AC(0)(仅限 64 位操作)- 如果启用对齐检查并在当前特权级别为 3 时进行未对齐的内存引用。
实地址模式异常
#GP(0)(仅限 128 位操作)- 如果内存操作数未对齐 16 字节边界,不论是哪一段。如果操作数的任何部分出现在 0 到 FFFFH 的有效地址空间之外。
#UD - 如果 CR0 中的 EM 设置为 1。(仅限 128 位操作)。如果 CR4 中的 OSFXSR 是 0。(仅限 128 位操作)。如果 CPUID 功能标志 SSE-2 为 0。
#NM - 如果 CR0 中的 TS 设置为 1。
#MF(仅限 64 位操作)- 如果存在未决的 x87 FPU 异常。
虚 8086 模式异常
与“实地址模式”中的异常相同。
#PF(错误代码) - 页错误。
#AC(0)(仅限 64 位操作)- 如果在启用对齐检查的情况下进行未对齐的内存引用。
数值异常
无。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PACKUSWB - 无符号饱和压缩
操作码 | 指令 | 说明 |
0F 67 /r | PACKUSWB mm, mm/m64 | 使用饱和运算将 mm 中的 4 个有符号字与 mm/m64 中的 4 个有符号字压缩成 8 个无符号字节,结果放入 mm。 |
66 0F 67 /r | PACKUSWB xmm1, xmm2/m128 | 使用饱和运算将 xmm1 与 xmm2/m128 中的有符号字压缩成无符号字节,结果放入 xmm1。 |
说明
使用饱和运算将目标操作数(第一个操作数)中的 4 个有符号字与源操作数(第二个操作数)中的 4 个有符号字压缩成 8 个有符号字节,结果放入目标操作数(请参阅“图 3-5”)。如果字的有符号值超出无符号字节的范围(即大于 FFH 或小于 00H),则分别将饱和字节值 FFH 或 00H 存储到目标操作数。
目标操作数必须是 MMX™ 技术寄存器;源操作数可以是 MMX 寄存器,也可以是四字内存位置。
将源操作数 xmm2/m128 中的八个有符号字与目标操作数 xmm1 中的八个有符号字压缩成十六个无符号字节,结果放入目标寄存器 xmm1。如果字的有符号值大于或小于无符号字节的范围,则对该值执行饱和运算(上溢时为 FFH,下溢时为 00H)。目标操作数是 XMM 寄存器。源操作数可以是 XMM 寄存器或 128 位内存操作数。
|
图 3-5. PACKUSWB 指令的操作
操作
PACKUSWB instruction with 64-bit operands:
DEST[7..0] SaturateSignedWordToUnsignedByte DEST[15..0];
DEST[15..8] SaturateSignedWordToUnsignedByte DEST[31..16];
DEST[23..16] SaturateSignedWordToUnsignedByte DEST[47..32];
DEST[31..24] SaturateSignedWordToUnsignedByte DEST[63..48];
DEST[39..32] SaturateSignedWordToUnsignedByte SRC[15..0];
DEST[47..40] SaturateSignedWordToUnsignedByte SRC[31..16];
DEST[55..48] SaturateSignedWordToUnsignedByte SRC[47..32];
DEST[63..56] SaturateSignedWordToUnsignedByte SRC[63..48];
PACKUSWB instruction with 128-bit operands:
DEST[7-0] SaturateSignedWordToUnsignedByte (DEST[15-0]);
DEST[15-8] SaturateSignedWordToUnsignedByte (DEST[31-16]);
DEST[23-16] SaturateSignedWordToUnsignedByte (DEST[47-32]);
DEST[31-24] SaturateSignedWordToUnsignedByte (DEST[63-48]);
DEST[39-32] SaturateSignedWordToUnsignedByte (DEST[79-64]);
DEST[47-40] SaturateSignedWordToUnsignedByte (DEST[95-80]);
DEST[55-48] SaturateSignedWordToUnsignedByte (DEST[111-96]);
DEST[63-56] SaturateSignedWordToUnsignedByte (DEST[127-112]);
DEST[71-64] SaturateSignedWordToUnsignedByte (SRC[15-0]);
DEST[79-72] SaturateSignedWordToUnsignedByte (SRC[31-16]);
DEST[87-80] SaturateSignedWordToUnsignedByte (SRC[47-32]);
DEST[95-88] SaturateSignedWordToUnsignedByte (SRC[63-48]);
DEST[103-96] SaturateSignedWordToUnsignedByte (SRC[79-64]);
DEST[111-104] SaturateSignedWordToUnsignedByte (SRC[95-80]);
DEST[119-112] SaturateSignedWordToUnsignedByte (SRC[111-96]);
DEST[127-120] SaturateSignedWordToUnsignedByte (SRC[127-112]);
英特尔(R) C++ 编译器等价内部函数
__m64 _mm_packs_pu16(__m64 m1, __m64 m2)
影响的标志
无。
保护模式异常
#GP(0) - 如果内存操作数有效地址超出 CS、DS、ES、FS 或 GS 段限制。(仅限 128 位操作)。如果内存操作数未对齐 16 字节边界,不论是哪一段。
#SS(0) - 如果内存操作数有效地址超出 SS 段限制。
#UD - 如果 CR0 中的 EM 设置为 1。(仅限 128 位操作)。如果 CR4 中的 OSFXSR 是 0。(仅限 128 位操作)。如果 CPUID 功能标志 SSE-2 为 0。
#NM - 如果 CR0 中的 TS 设置为 1。
#MF(仅限 64 位操作)- 如果存在未决的 x87 FPU 异常。
#PF(错误代码) - 如果发生页错误。
#AC(0)(仅限 64 位操作)- 如果启用对齐检查并在当前特权级别为 3 时进行未对齐的内存引用。
实地址模式异常
#GP(0)(仅限 128 位操作)- 如果内存操作数未对齐 16 字节边界,不论是哪一段。如果操作数的任何部分出现在 0 到 FFFFH 的有效地址空间之外。
#UD - 如果 CR0 中的 EM 设置为 1。(仅限 128 位操作)。如果 CR4 中的 OSFXSR 是 0。(仅限 128 位操作)。如果 CPUID 功能标志 SSE-2 为 0。
#NM - 如果 CR0 中的 TS 设置为 1。
#MF(仅限 64 位操作)- 如果存在未决的 x87 FPU 异常。
虚 8086 模式异常
与“实地址模式”中的异常相同。
#PF(错误代码) - 页错误。
#AC(0)(仅限 64 位操作)- 如果在启用对齐检查的情况下进行未对齐的内存引用。
---------------------------------------------------------------------------------------------------------------------------------------
PACKSSWB/PACKSSDW - 有符号饱和压缩
操作码 | 指令 | 说明 |
0F 63 /r | PACKSSWB mm1, mm2/m64 | 使用饱和运算将 mm1 中的 4 个与 mm2/m64 中的 4 个压缩有符号字整数压缩成 8 个压缩有符号字节整数,结果放入 mm1。 |
66 0F 63 /r | PACKSSWB xmm1, xmm2/m128 | 使用饱和运算将 xmm1 中的 8 个与 xxm2/m128 中的 8 个压缩有符号字整数压缩成 16 个压缩有符号字节整数,结果放入 xxm1。 |
0F 6B /r | PACKSSDW mm1, mm2/m64 | 使用饱和运算将 mm1 中的 2 个与 mm2/m64 中的 2 个压缩有符号双字整数压缩成 4 个压缩有符号字整数,结果放入 mm1。 |
66 0F 6B /r | PACKSSDW xmm1, xmm2/m128 | 使用饱和运算将 xmm1 中的 4 个与 xxm2/m128 中的 4 个压缩有符号双字整数压缩成 8 个压缩有符号字整数,结果放入 xxm1。 |
说明
使用饱和运算将压缩有符号字整数压缩成压缩有符号字节整数 (PACKSSWB),或是将压缩有符号双字整数压缩成压缩有符号字整数 (PACKSSDW)。PACKSSWB 指令将目标操作数(第一个操作数)中的 4 个有符号字与源操作数(第二个操作数)中的 4 个有符号字压缩成 8 个有符号字节,结果放入目标操作数。如果字的有符号值超出有符号字节的范围(即大于 7FH 或小于 80H),则分别将饱和字节值 7FH 或 80H 存储到目标操作数。
PACKSSDW 指令将目标操作数(第一个操作数)中的 2 个有符号双字与源操作数(第二个操作数)中的 2 个有符号双字压缩成 4 个有符号字,结果放入目标操作数(请参阅“图 3-4”)。如果双字的有符号值超出有符号字的范围(即大于 7FFFH 或小于 8000H),则分别将饱和字节值 7FFFH 或 8000H 存储到目标操作数。
PACKSSWB 与 PACKSSDW 指令的目标操作数必须是 MMX™ 技术寄存器;源操作数可以是 MMX 寄存器,也可以是四字内存位置。
使用有符号饱和运算压缩源操作数与目标操作数中的有符号数据元素,结果写入目标操作数。目标操作数是 XMM 寄存器。源操作数可以是 XMM 寄存器或 128 位内存操作数。
PACKSSWB 指令将源操作数中的八个有符号字与目标操作数中的八个有符号字压缩成十六个有符号字节,结果放入目标操作数。如果字的有符号值大于或小于有符号字节的范围,则对该值执行饱和运算(上溢时 7FH,下溢时 80H)。
PACKSSDW 指令将源操作数中的四个有符号双字与目标操作数中的四个有符号双字压缩成八个有符号字,结果放入目标寄存器。如果双字的有符号值大于或小于有符号字的范围,则对该值执行饱和运算(上溢时 7FFFH,下溢时 8000H))。
|
图 3-4. PACKSSDW 指令的操作
操作
PACKSSWB instruction with 64-bit operands
DEST[7..0] SaturateSignedWordToSignedByte DEST[15..0];
DEST[15..8] SaturateSignedWordToSignedByte DEST[31..16];
DEST[23..16] SaturateSignedWordToSignedByte DEST[47..32];
DEST[31..24] SaturateSignedWordToSignedByte DEST[63..48];
DEST[39..32] SaturateSignedWordToSignedByte SRC[15..0];
DEST[47..40] SaturateSignedWordToSignedByte SRC[31..16];
DEST[55..48] SaturateSignedWordToSignedByte SRC[47..32];
DEST[63..56] SaturateSignedWordToSignedByte SRC[63..48];
PACKSSDW instruction with 64-bit operands
DEST[15..0] SaturateSignedDoublewordToSignedWord DEST[31..0];
DEST[31..16] SaturateSignedDoublewordToSignedWord DEST[63..32];
DEST[47..32] SaturateSignedDoublewordToSignedWord SRC[31..0];
DEST[63..48] SaturateSignedDoublewordToSignedWord SRC[63..32];
PACKSSWB instruction with 128-bit operands
DEST[7-0] SaturateSignedWordToSignedByte (DEST[15-0]);
DEST[15-8] SaturateSignedWordToSignedByte (DEST[31-16]);
DEST[23-16] SaturateSignedWordToSignedByte (DEST[47-32]);
DEST[31-24] SaturateSignedWordToSignedByte (DEST[63-48]);
DEST[39-32] SaturateSignedWordToSignedByte (DEST[79-64]);
DEST[47-40] SaturateSignedWordToSignedByte (DEST[95-80]);
DEST[55-48] SaturateSignedWordToSignedByte (DEST[111-96]);
DEST[63-56] SaturateSignedWordToSignedByte (DEST[127-112]);
DEST[71-64] SaturateSignedWordToSignedByte (SRC[15-0]);
DEST[79-72] SaturateSignedWordToSignedByte (SRC[31-16]);
DEST[87-80] SaturateSignedWordToSignedByte (SRC[47-32]);
DEST[95-88] SaturateSignedWordToSignedByte (SRC[63-48]);
DEST[103-96] SaturateSignedWordToSignedByte (SRC[79-64]);
DEST[111-104] SaturateSignedWordToSignedByte (SRC[95-80]);
DEST[119-112] SaturateSignedWordToSignedByte (SRC[111-96]);
DEST[127-120] SaturateSignedWordToSignedByte (SRC[127-112]);
PACKSSDW instruction with 128-bit operands
DEST[15-0] SaturateSignedDwordToSignedWord (DEST[31-0]);
DEST[31-16] SaturateSignedDwordToSignedWord (DEST[63-32]);
DEST[47-32] SaturateSignedDwordToSignedWord (DEST[95-64]);
DEST[63-48] SaturateSignedDwordToSignedWord (DEST[127-96]);
DEST[79-64] SaturateSignedDwordToSignedWord (SRC[31-0]);
DEST[95-80] SaturateSignedDwordToSignedWord (SRC[63-32]);
DEST[111-96] SaturateSignedDwordToSignedWord (SRC[95-64]);
DEST[127-112] SaturateSignedDwordToSignedWord (SRC[127-96]);
英特尔(R) C++ 编译器等价内部函数
__m64 _mm_packs_pi16(__m64 m1, __m64 m2)
__m64 _mm_packs_pi32 (__m64 m1, __m64 m2)
影响的标志
无。
保护模式异常
#GP(0) - 如果内存操作数有效地址超出 CS、DS、ES、FS 或 GS 段限制。(仅限 128 位操作)。如果内存操作数未对齐 16 字节边界,不论是哪一段。
#SS(0) - 如果内存操作数有效地址超出 SS 段限制。
#UD - 如果 CR0 中的 EM 设置为 1。(仅限 128 位操作)。如果 CR4 中的 OSFXSR 是 0。(仅限 128 位操作)。如果 CPUID 功能标志 SSE-2 为 0。
#NM - 如果 CR0 中的 TS 设置为 1。
#MF(仅限 64 位操作)- 如果存在未决的 x87 FPU 异常。
#PF(错误代码) - 如果发生页错误。
#AC(0)(仅限 64 位操作)- 如果启用对齐检查并在当前特权级别为 3 时进行未对齐的内存引用。
实地址模式异常
#GP(0)(仅限 128 位操作)- 如果内存操作数未对齐 16 字节边界,不论是哪一段。如果操作数的任何部分出现在 0 到 FFFFH 的有效地址空间之外。
#UD - 如果 CR0 中的 EM 设置为 1。(仅限 128 位操作)。如果 CR4 中的 OSFXSR 是 0。(仅限 128 位操作)。如果 CPUID 功能标志 SSE-2 为 0。
#NM - 如果 CR0 中的 TS 设置为 1。
#MF(仅限 64 位操作)- 如果存在未决的 x87 FPU 异常。
虚 8086 模式异常
与“实地址模式”中的异常相同。
#PF(错误代码) - 页错误。
#AC(0)(仅限 64 位操作)- 如果在启用对齐检查的情况下进行未对齐的内存引用。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PMULLW - 压缩有符号乘法取低位
操作码 | 指令 | 说明 |
0F D5 /r | PMULLW mm, mm/m64 | 将 mm1 寄存器与 mm2/m64 中的压缩有符号字整数相乘,并将结果的低 16 位存储到 mm1。 |
66 0F D5 /r | PMULLW xmm1, xmm2/m128 | 将 xmm1 与 xmm2/m128 中的压缩有符号字整数相乘,并将结果的低 16 位存储到 xmm1。 |
说明
对目标操作数(第一个操作数)与源操作数(第二个操作数)中的压缩有符号字整数执行 SIMD 乘法,并将每个 32 位中间结果的低 16 位存储到目标操作数。(下图显示此操作使用 64 位操作数时的情况)。源操作数可以是 MMX™ 技术寄存器或 64 位内存位置,也可以是 XMM 寄存器或 128 位内存位置。目标操作数可以是 MMX 或 XMM 寄存器。
|
图 3-8. PMULLU 指令操作
操作
PMULLW instruction with 64-bit operands:
TEMP0[31-0] DEST[15-0] * SRC[15-0]; * Signed multiplication *
TEMP1[31-0] DEST[31-16] * SRC[31-16];
TEMP2[31-0] DEST[47-32] * SRC[47-32];
TEMP3[31-0] DEST[63-48] * SRC[63-48];
DEST[15-0] TEMP0[15-0];
DEST[31-16] TEMP1[15-0];
DEST[47-32] TEMP2[15-0];
DEST[63-48] TEMP3[15-0];
PMULLW instruction with 64-bit operands:
TEMP0[31-0] DEST[15-0] * SRC[15-0]; * Signed multiplication *
TEMP1[31-0] DEST[31-16] * SRC[31-16];
TEMP2[31-0] DEST[47-32] * SRC[47-32];
TEMP3[31-0] DEST[63-48] * SRC[63-48];
TEMP4[31-0] DEST[79-64] * SRC[79-64];
TEMP5[31-0] DEST[95-80] * SRC[95-80];
TEMP6[31-0] DEST[111-96] * SRC[111-96];
TEMP7[31-0] DEST[127-112] * SRC[127-112];
DEST[15-0] TEMP0[15-0];
DEST[31-16] TEMP1[15-0];
DEST[47-32] TEMP2[15-0];
DEST[63-48] TEMP3[15-0];
DEST[79-64] TEMP4[15-0];
DEST[95-80] TEMP5[15-0];
DEST[111-96] TEMP6[15-0];
DEST[127-112] TEMP7[15-0];
英特尔(R) C++ 编译器等价内部函数
PMULLW __m64 _mm_mullo_pi16(__m64 m1, __m64 m2)
PMULLW __m128i _mm_mullo_epi16 ( __m128i a, __m128i b)
影响的标志
无。
保护模式异常
#GP(0) - 如果内存操作数有效地址超出 CS、DS、ES、FS 或 GS 段限制。(仅限 128 位操作)。如果内存操作数未对齐 16 字节边界,不论是哪一段。
#SS(0) - 如果内存操作数有效地址超出 SS 段限制。
#UD - 如果 CR0 中的 EM 设置为 1。(仅限 128 位操作)。如果 CR4 中的 OSFXSR 是 0。(仅限 128 位操作)。如果 CPUID 功能标志 SSE-2 为 0。
#NM - 如果 CR0 中的 TS 设置为 1。
#MF(仅限 64 位操作)- 如果存在未决的 x87 FPU 异常。
#PF(错误代码) - 如果发生页错误。
#AC(0)(仅限 64 位操作)- 如果启用对齐检查并在当前特权级别为 3 时进行未对齐的内存引用。
实地址模式异常
#GP(0)(仅限 128 位操作)- 如果内存操作数未对齐 16 字节边界,不论是哪一段。如果操作数的任何部分出现在 0 到 FFFFH 的有效地址空间之外。
#UD - 如果 CR0 中的 EM 设置为 1。(仅限 128 位操作)。如果 CR4 中的 OSFXSR 是 0。(仅限 128 位操作)。如果 CPUID 功能标志 SSE-2 为 0。
#NM - 如果 CR0 中的 TS 设置为 1。
#MF(仅限 64 位操作)- 如果存在未决的 x87 FPU 异常。
虚 8086 模式异常
与“实地址模式”中的异常相同
#PF(错误代码) - 页错误。
#AC(0)(仅限 64 位操作)- 如果在启用对齐检查的情况下进行未对齐的内存引用。
数值异常
无。
-----------------------------------------------------------------------------------------------------------------------------------------------
PSLLDQ - 压缩双四字逻辑左移
操作码 | 指令 | 说明 |
66 0F 73 /7 ib | PSLLDQ xmm1, imm8 | 将 xmm1 左移 imm8 字节,清除低位。 |
说明
按计数操作数(第二个操作数)指定的字节数,将目标操作数(第一个操作数)左移。空出的低位字节被清除(设置为全 0)。如果计数操作数指定的值大于 15,则将目标操作数设置为全 0。目标操作数是 XMM 寄存器。计数操作数是 8 位立即数。
操作
TEMP COUNT;
if (TEMP > 15) TEMP 16;
DEST DEST << (TEMP * 8);
英特尔(R) C++ 编译器等价内部函数
PSLLDQ __m128i _mm_slli_si128 ( __m128i a, int imm)
影响的标志
无。
保护模式异常
#UD - 如果 CR0 中的 EM 设置为 1。如果 CR4 中的 OSFXSR 是 0。如果 CPUID 功能标志 SSE-2 是 0。
#NM - 如果 CR0 中的 TS 设置为 1。
实地址模式异常
与“保护模式”中的异常相同。
虚 8086 模式异常
与“保护模式”中的异常相同。
数值异常
无。
-----------------------------------------------------------------------------------------------------------------------------------------------
PSHUFD - 压缩双字乱序
操作码 | 指令 | 说明 |
66 0F 70 /r ib | PSHUFD xmm1, xmm2/m128,imm8 | 按照 imm8 中的编码对 xmm2/m128 中的双字执行乱序处理,结果存储到 xmm1。 |
说明
从源操作数(第二个操作数)中复制双字,按照顺序操作数(第三个操作数)选择的位置,将它们插入目标操作数(第一个操作数)。图 3-10 显示 PSHUFD 指令的操作与顺序操作数的编码。顺序操作数中的每 2 个位字段选择目标操作数中一个双字位置的内容。例如,顺序操作数的位 0 与 1 选择目标操作数中双字 0 的内容。顺序操作数位 0 与 1 的编码(请参阅“图 3-10”中的字段编码)确定要将源操作数中的哪个双字复制到目标操作数的双字 0。
源操作数可以是 XMM 寄存器或 128 位内存位置。目标操作数是 XMM 寄存器。顺序操作数是 8 位立即数。
请注意,此指令允许将源操作数中的一个双字复制到目标操作数中的多个双字位置。
|
图 3-10 PSHUFD 指令操作
操作
DEST[31-0] (SRC >> (ORDER[1-0] * 32) )[31-0]
DEST[63-32] (SRC >> (ORDER[3-2] * 32) )[31-0]
DEST[95-64] (SRC >> (ORDER[5-4] * 32) )[31-0]
DEST[127-96] (SRC >> (ORDER[7-6] * 32) )[31-0]
英特尔(R) C++ 编译器等价内部函数
PSHUFD __m128i _mm_shuffle_epi32(__m128i a, int n)
影响的标志
无。
保护模式异常
#GP(0) - 如果内存操作数有效地址超出 CS、DS、ES、FS 或 GS 段限制。如果内存操作数未对齐 16 字节边界,不论是哪一段。
#SS(0) - 如果内存操作数有效地址超出 SS 段限制。
#UD - 如果 CR0 中的 EM 设置为 1。如果 CR4 中的 OSFXSR 是 0。如果 CPUID 功能标志 SSE-2 是 0。
#NM - 如果 CR0 中的 TS 设置为 1。
#PF(错误代码) - 如果发生页错误。
实地址模式异常
#GP(0) - 如果内存操作数未对齐 16 字节边界,不论是哪一段。如果操作数的任何部分出现在 0 到 FFFFH 的有效地址空间之外。
#UD - 如果 CR0 中的 EM 设置为 1。如果 CR4 中的 OSFXSR 是 0。如果 CPUID 功能标志 SSE-2 为 0。
#NM - 如果 CR0 中的 TS 设置为 1。
虚 8086 模式异常
与“实地址模式”中的异常相同。
#PF(错误代码) - 页错误。
数值异常
无。
这篇关于MMX指令集(详解)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!