SIMD——MMX指令集介绍

MMX指令集共47个指令,分为以下几类:
• Data transfer
• Arithmetic
• Comparison
• Conversion
• Unpacking
• Logical
• Shift
• Empty MMX state instruction (EMMS)

这里写图片描述

1. Data Transfer(数据转移)

从内存到MMX寄存器/ 从MMX寄存器到内存/ 从通用寄存器到MMX寄存器/ 从MMX寄存器到通用寄存器

  • MOVD 指令(32位)——4个
指令函数指令描述
movd__m64 _mm_cvtsi32_si64(int a)
__m64 _m_from_int(int a)
变量a的32位拷贝到MMX寄存器的低32位,高32位置零
movdint _mm_cvtsi64_si32 (__m64 a)
int _m_to_int(__m64 a)
MMX变量的低32位拷贝到int类型中

根据 https://msdn.microsoft.com/zh-cn/8w48hs3e(v=vs.80) 所属 _mm_cvtsi32_si64 与 _m_from_int 应相同。(请指点)

+MOVQ指令(64位)——4个

指令函数指令描述
movq__int64 _mm_cvtm64_si64(__m64 a)
__int64 _m_to_int64(__m64 a)
拷贝64位整型a到结果
movq__m64 _mm_cvtsi64_m64 (__int64 a)
__m64 _m_from_int64(__int64 a)
拷贝64位整型a到结果

2.Arithmetic(数值计算)

进行压缩整数的加减乘以及multiply/add计算。

加法(7个指令,14个函数):

指令函数指令描述
paddw__m64 _mm_add_pi16(__m64 a, __m64 b)
__m64 _m_paddw(__m64 a, __m64 b)
Add packed word integers(16位) with wraparound
使用wraparound截断溢出方式进行压缩字整数的加运算
paddd__m64 _mm_add_pi32(__m64 a, __m64 b)
__m64 _m_paddd (__m64a, __m64 b)
Add packed doubleword integers(32位) with wraparound
使用wraparound截断溢出方式进行压缩双字整数的加运算
paddb__m64 _mm_add_pi8(__m64 a, __m64 b)
__m64 _m_paddb (__m64a, __m64 b)
Add packed byte integers(8位) with wraparound
使用wraparound截断溢出方式进行压缩字节整数的加运算
paddsw__m64 _mm_adds_pi16(__m64 a, __m64 b)
__m64 _m_paddsw(__m64 a, __m64 b)
Add packed word integers with signed saturation
压缩字整数的有符号饱和加运算
paddsb__m64 _mm_adds_pi8(__m64 a, __m64 b)
__m64 _m_paddsb(__m64 a, __m64 b)
Add packed byte integers with signed saturation
压缩字节整数的有符号饱和加运算
paddusw__m64 _mm_adds_pu16(__m64 a, __m64 b)
__m64 _m_paddusw(__m64 a, __m64 b)
Add packed word integers with unsigned saturation
压缩字整数的无符号饱和加运算
paddusb__m64 _mm_adds_pu8(__m64 a, __m64 b)
__m64 _m_paddusb(__m64 a, __m64 b)
Add packed byte integers with unsigned saturation
压缩字节整数的无符号饱和加运算

减法(7个指令,14个函数):

指令函数指令描述
psubw__m64 _mm_sub_pi16(__m64 a, __m64 b)
__m64 _m_psubw(__m64 a, __m64 b)
sub packed word integers(16位) with wraparound
使用wraparound截断溢出方式进行压缩字整数的减运算
psubd__m64 _mm_sub_pi32(__m64 a, __m64 b)
__m64 _m_psubd (__m64a, __m64 b)
sub packed doubleword integers(32位) with wraparound
使用wraparound截断溢出方式进行压缩双字整数的减运算
psubb__m64 _mm_sub_pi8(__m64 a, __m64 b)
__m64 _m_psubb (__m64a, __m64 b)
sub packed byte integers(8位) with wraparound
使用wraparound截断溢出方式进行压缩字节整数的减运算
psubsw__m64 _mm_subs_pi16(__m64 a, __m64 b)
__m64 _m_psubsw(__m64 a, __m64 b)
sub packed word integers with signed saturation
压缩字整数的有符号饱和减运算
psubsb__m64 _mm_subs_pi8(__m64 a, __m64 b)
__m64 _m_psubsb(__m64 a, __m64 b)
sub packed byte integers with signed saturation
压缩字节整数的有符号饱和减运算
psubusw__m64 _mm_subs_pu16(__m64 a, __m64 b)
__m64 _m_psubusw(__m64 a, __m64 b)
sub packed word integers with unsigned saturation
压缩字整数的无符号饱和减运算
psubusb__m64 _mm_subs_pu8(__m64 a, __m64 b)
__m64 _m_psubusb(__m64 a, __m64 b)
sub packed byte integers with unsigned saturation
压缩字节整数的无符号饱和减运算

乘法(2个指令,4个函数)

指令函数指令描述
pmulhw__m64 _mulhi_pi16(__m64 a, __m64 b)
__m64 _m_pmulhw (__m64 a,__m64 b)
压缩16位字整数a和b相乘会产生32位双字整数,将32位整数的高16位存储在结果中
pmullw__m64_mullo_pi16(__m64 a, __m64 b)
__m64 _m_pmullw(__m64 a,__m64 b)
压缩16位字整数a和b相乘会产生32位双字整数,将32位整数的低16位存储在结果中

具体的执行方式请参考下图,若使用pmulhw则乘法结果中的高16位存储在C中,若使用pmullw则乘法结果中的低16位存储在C中。
这里写图片描述

multiply/add(乘法加和,1个指令,2个函数)

指令函数指令描述
pmaddwd__m64 _madd_pi16(__m64 a, __m64 b)
__m64 _m_pmaddwd (__m64 a,__m64 b)
压缩16位字整数a和b相乘会产生32位双字整数,a和b中后2个8位的相乘结果的和保存在结果的低32位,前2个16位相乘结果的和保存在结果的高32位中

具体的执行情况参考下图:

这里写图片描述

3. Comparision(比较操作)

指令函数指令描述
pcmpeqb__m64 _mm_cmpeq_pi8 (__m64 a, __m64 b)
__m64 _m_pcmpeqb (__m64 a, __m64 b)
比较a和b里的8位字节整数值进行比较,判断它们是否相等,相等返回OxFFFF,否则返回0
pcmpeqw__m64 _mm_cmpeq_pi16 (__m64 a, __m64 b)
__m64 _m_pcmpeqw (__m64 a, __m64 b)
比较a和b里的16位字整数值进行比较,判断它们是否相等,相等返回OxFFFF,否则返回0
pcmpeqd__m64 _mm_cmpeq_pi32 (__m64 a, __m64 b)
__m64 _m_pcmpeqd (__m64 a, __m64 b)
比较a和b里的32位双字整数值进行比较,判断它们是否相等,相等返回OxFFFF,否则返回0
pcmpgtb__m64 _mm_cmpgt_pi8 (__m64 a, __m64 b)
__m64 _m_pcmpgtb (__m64 a, __m64 b)
比较a和b里的8位字节整数值,如果a中>b中,放回OxFFFF,否则返回0
pcmpgtw__m64 _mm_cmpgt_pi16 (__m64 a, __m64 b)
__m64 _m_pcmpgtw (__m64 a, __m64 b)
比较a和b里的16位字整数值,如果a中>b中,放回OxFFFF,否则返回0
pcmpgtd__m64 _mm_cmpgt_pi32 (__m64 a, __m64 b)
__m64 _m_pcmpgtd (__m64 a, __m64 b)
比较a和b里的32位双字整数值,如果a中>b中,放回OxFFFF,否则返回0

4. Conversion(打包指令)

指令函数指令描述
packsswb__m64 _mm_packs_pi16 (__m64 a, __m64 b)
__m64 _m_packsswb (__m64 a, __m64 b)
将压缩16位字整数a和bpack成8位字节整数使用有符号饱和运算,保存到结果中
packssdw__m64 _mm_packs_pi32 (__m64 a, __m64 b)
__m64 _m_packssdw (__m64 a, __m64 b)
将压缩32位双字整数a和b pack成16位字整数使用有符号饱和运算,保存到结果中
packuswb__m64 _mm_packs_pu16 (__m64 a, __m64 b)
__m64 _m_packuswb (__m64 a, __m64 b)
将压缩16位字整数a和b pack成8位字节整数使用无符号饱和运算,保存到结果中

packsswb:

dst[7:0] := Saturate_Int16_To_Int8 (a[15:0])
dst[15:8] := Saturate_Int16_To_Int8 (a[31:16])
dst[23:16] := Saturate_Int16_To_Int8 (a[47:32])
dst[31:24] := Saturate_Int16_To_Int8 (a[63:48])
dst[39:32] := Saturate_Int16_To_Int8 (b[15:0])
dst[47:40] := Saturate_Int16_To_Int8 (b[31:16])
dst[55:48] := Saturate_Int16_To_Int8 (b[47:32])
dst[63:56] := Saturate_Int16_To_Int8 (b[63:48])

packssdw:

dst[15:0] := Saturate_Int32_To_Int16 (a[31:0])
dst[31:16] := Saturate_Int32_To_Int16 (a[63:32])
dst[47:32] := Saturate_Int32_To_Int16 (b[31:0])
dst[63:48] := Saturate_Int32_To_Int16 (b[63:32])

packuswb:

dst[7:0] := Saturate_Int16_To_UnsignedInt8 (a[15:0])
dst[15:8] := Saturate_Int16_To_UnsignedInt8 (a[31:16])
dst[23:16] := Saturate_Int16_To_UnsignedInt8 (a[47:32])
dst[31:24] := Saturate_Int16_To_UnsignedInt8 (a[63:48])
dst[39:32] := Saturate_Int16_To_UnsignedInt8 (b[15:0])
dst[47:40] := Saturate_Int16_To_UnsignedInt8 (b[31:16])
dst[55:48] := Saturate_Int16_To_UnsignedInt8 (b[47:32])
dst[63:56] := Saturate_Int16_To_UnsignedInt8 (b[63:48])

5.Unpack(解包指令)

指令函数指令描述
punpckhbw__m64 _m_punpckhbw (__m64 a, __m64 b)
__m64 _mm_unpackhi_pi8 (__m64 a, __m64 b)
64位a和b数据的高一半位数数据(32位)保存到结果中,具体保存方式参考如下描述
punpckhwd
punpckhdq
punpcklbw
punpcklwd
punpckldq

packsswb:

INTERLEAVE_HIGH_BYTES(src1[63:0], src2[63:0]){
    dst[7:0] := src1[39:32]
    dst[15:8] := src2[39:32] 
    dst[23:16] := src1[47:40]
    dst[31:24] := src2[47:40]
    dst[39:32] := src1[55:48]
    dst[47:40] := src2[55:48]
    dst[55:48] := src1[63:56]
    dst[63:56] := src2[63:56]
    RETURN dst[63:0]
}   

dst[63:0] := INTERLEAVE_HIGH_BYTES(a[63:0], b[63:0])

6. Logical(逻辑运算)

指令函数指令描述
pand
pandn
por
pxor

7. Shift(移位)

指令函数指令描述
psllw
pslld
psllq
psrlw
psrld
psrlq
psraw
psrad

8. EMMS

指令函数指令描述
emmsvoid _m_empty (void)void _mm_empty (void)使用 EMMS 命令与空容器以容纳新目录

EMMS使用方法:
1. 如果下一条命令是浮点命令,请在MMX指令后使用_mm_empty(例如在进行float,double和long double 类型的计算前)
2. 当寄存器中不存在MMX寄存时,不要使用EMMS指令。如果下一个命令使用MMX寄存器,使用EMMS没有好处(不会进行优化)
3.

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值