SIMD——MMX指令集介绍
MMX指令集共47個(gè)指令,分為以下幾類: 
 ? Data transfer 
 ? Arithmetic 
 ? Comparison 
 ? Conversion 
 ? Unpacking 
 ? Logical 
 ? Shift 
 ? Empty MMX state instruction (EMMS)
1. Data Transfer(數(shù)據(jù)轉(zhuǎn)移)
從內(nèi)存到MMX寄存器/ 從MMX寄存器到內(nèi)存/ 從通用寄存器到MMX寄存器/ 從MMX寄存器到通用寄存器
- MOVD 指令(32位)——4個(gè)
| movd | __m64 _mm_cvtsi32_si64(int a) __m64 _m_from_int(int a) | 變量a的32位拷貝到MMX寄存器的低32位,高32位置零 | 
| movd | int _mm_cvtsi64_si32 (__m64 a) int _m_to_int(__m64 a) | MMX變量的低32位拷貝到int類型中 | 
根據(jù) https://msdn.microsoft.com/zh-cn/8w48hs3e(v=vs.80) 所屬 _mm_cvtsi32_si64 與 _m_from_int 應(yīng)相同。(請(qǐng)指點(diǎn))
+MOVQ指令(64位)——4個(gè)
| movq | __int64 _mm_cvtm64_si64(__m64 a) __int64 _m_to_int64(__m64 a) | 拷貝64位整型a到結(jié)果 | 
| movq | __m64 _mm_cvtsi64_m64 (__int64 a) __m64 _m_from_int64(__int64 a) | 拷貝64位整型a到結(jié)果 | 
2.Arithmetic(數(shù)值計(jì)算)
進(jìn)行壓縮整數(shù)的加減乘以及multiply/add計(jì)算。
加法(7個(gè)指令,14個(gè)函數(shù)):
| paddw | __m64 _mm_add_pi16(__m64 a, __m64 b) __m64 _m_paddw(__m64 a, __m64 b) | Add packed word integers(16位) with wraparound 使用wraparound截?cái)嘁绯龇绞竭M(jìn)行壓縮字整數(shù)的加運(yùn)算 | 
| paddd | __m64 _mm_add_pi32(__m64 a, __m64 b) __m64 _m_paddd (__m64a, __m64 b) | Add packed doubleword integers(32位) with wraparound 使用wraparound截?cái)嘁绯龇绞竭M(jìn)行壓縮雙字整數(shù)的加運(yùn)算 | 
| paddb | __m64 _mm_add_pi8(__m64 a, __m64 b) __m64 _m_paddb (__m64a, __m64 b) | Add packed byte integers(8位) with wraparound 使用wraparound截?cái)嘁绯龇绞竭M(jìn)行壓縮字節(jié)整數(shù)的加運(yùn)算 | 
| paddsw | __m64 _mm_adds_pi16(__m64 a, __m64 b) __m64 _m_paddsw(__m64 a, __m64 b) | Add packed word integers with signed saturation 壓縮字整數(shù)的有符號(hào)飽和加運(yùn)算 | 
| paddsb | __m64 _mm_adds_pi8(__m64 a, __m64 b) __m64 _m_paddsb(__m64 a, __m64 b) | Add packed byte integers with signed saturation 壓縮字節(jié)整數(shù)的有符號(hào)飽和加運(yùn)算 | 
| paddusw | __m64 _mm_adds_pu16(__m64 a, __m64 b) __m64 _m_paddusw(__m64 a, __m64 b) | Add packed word integers with unsigned saturation 壓縮字整數(shù)的無(wú)符號(hào)飽和加運(yùn)算 | 
| paddusb | __m64 _mm_adds_pu8(__m64 a, __m64 b) __m64 _m_paddusb(__m64 a, __m64 b) | Add packed byte integers with unsigned saturation 壓縮字節(jié)整數(shù)的無(wú)符號(hào)飽和加運(yùn)算 | 
減法(7個(gè)指令,14個(gè)函數(shù)):
| psubw | __m64 _mm_sub_pi16(__m64 a, __m64 b) __m64 _m_psubw(__m64 a, __m64 b) | sub packed word integers(16位) with wraparound 使用wraparound截?cái)嘁绯龇绞竭M(jìn)行壓縮字整數(shù)的減運(yùn)算 | 
| psubd | __m64 _mm_sub_pi32(__m64 a, __m64 b) __m64 _m_psubd (__m64a, __m64 b) | sub packed doubleword integers(32位) with wraparound 使用wraparound截?cái)嘁绯龇绞竭M(jìn)行壓縮雙字整數(shù)的減運(yùn)算 | 
| psubb | __m64 _mm_sub_pi8(__m64 a, __m64 b) __m64 _m_psubb (__m64a, __m64 b) | sub packed byte integers(8位) with wraparound 使用wraparound截?cái)嘁绯龇绞竭M(jìn)行壓縮字節(jié)整數(shù)的減運(yùn)算 | 
| psubsw | __m64 _mm_subs_pi16(__m64 a, __m64 b) __m64 _m_psubsw(__m64 a, __m64 b) | sub packed word integers with signed saturation 壓縮字整數(shù)的有符號(hào)飽和減運(yùn)算 | 
| psubsb | __m64 _mm_subs_pi8(__m64 a, __m64 b) __m64 _m_psubsb(__m64 a, __m64 b) | sub packed byte integers with signed saturation 壓縮字節(jié)整數(shù)的有符號(hào)飽和減運(yùn)算 | 
| psubusw | __m64 _mm_subs_pu16(__m64 a, __m64 b) __m64 _m_psubusw(__m64 a, __m64 b) | sub packed word integers with unsigned saturation 壓縮字整數(shù)的無(wú)符號(hào)飽和減運(yùn)算 | 
| psubusb | __m64 _mm_subs_pu8(__m64 a, __m64 b) __m64 _m_psubusb(__m64 a, __m64 b) | sub packed byte integers with unsigned saturation 壓縮字節(jié)整數(shù)的無(wú)符號(hào)飽和減運(yùn)算 | 
乘法(2個(gè)指令,4個(gè)函數(shù))
| pmulhw | __m64 _mulhi_pi16(__m64 a, __m64 b) __m64 _m_pmulhw (__m64 a,__m64 b) | 壓縮16位字整數(shù)a和b相乘會(huì)產(chǎn)生32位雙字整數(shù),將32位整數(shù)的高16位存儲(chǔ)在結(jié)果中 | 
| pmullw | __m64_mullo_pi16(__m64 a, __m64 b) __m64 _m_pmullw(__m64 a,__m64 b) | 壓縮16位字整數(shù)a和b相乘會(huì)產(chǎn)生32位雙字整數(shù),將32位整數(shù)的低16位存儲(chǔ)在結(jié)果中 | 
具體的執(zhí)行方式請(qǐng)參考下圖,若使用pmulhw則乘法結(jié)果中的高16位存儲(chǔ)在C中,若使用pmullw則乘法結(jié)果中的低16位存儲(chǔ)在C中。 
 
multiply/add(乘法加和,1個(gè)指令,2個(gè)函數(shù))
| pmaddwd | __m64 _madd_pi16(__m64 a, __m64 b) __m64 _m_pmaddwd (__m64 a,__m64 b) | 壓縮16位字整數(shù)a和b相乘會(huì)產(chǎn)生32位雙字整數(shù),a和b中后2個(gè)8位的相乘結(jié)果的和保存在結(jié)果的低32位,前2個(gè)16位相乘結(jié)果的和保存在結(jié)果的高32位中 | 
具體的執(zhí)行情況參考下圖:
3. Comparision(比較操作)
| pcmpeqb | __m64 _mm_cmpeq_pi8 (__m64 a, __m64 b) __m64 _m_pcmpeqb (__m64 a, __m64 b) | 比較a和b里的8位字節(jié)整數(shù)值進(jìn)行比較,判斷它們是否相等,相等返回OxFFFF,否則返回0 | 
| pcmpeqw | __m64 _mm_cmpeq_pi16 (__m64 a, __m64 b) __m64 _m_pcmpeqw (__m64 a, __m64 b) | 比較a和b里的16位字整數(shù)值進(jìn)行比較,判斷它們是否相等,相等返回OxFFFF,否則返回0 | 
| pcmpeqd | __m64 _mm_cmpeq_pi32 (__m64 a, __m64 b) __m64 _m_pcmpeqd (__m64 a, __m64 b) | 比較a和b里的32位雙字整數(shù)值進(jìn)行比較,判斷它們是否相等,相等返回OxFFFF,否則返回0 | 
| pcmpgtb | __m64 _mm_cmpgt_pi8 (__m64 a, __m64 b) __m64 _m_pcmpgtb (__m64 a, __m64 b) | 比較a和b里的8位字節(jié)整數(shù)值,如果a中>b中,放回OxFFFF,否則返回0 | 
| pcmpgtw | __m64 _mm_cmpgt_pi16 (__m64 a, __m64 b) __m64 _m_pcmpgtw (__m64 a, __m64 b) | 比較a和b里的16位字整數(shù)值,如果a中>b中,放回OxFFFF,否則返回0 | 
| pcmpgtd | __m64 _mm_cmpgt_pi32 (__m64 a, __m64 b) __m64 _m_pcmpgtd (__m64 a, __m64 b) | 比較a和b里的32位雙字整數(shù)值,如果a中>b中,放回OxFFFF,否則返回0 | 
4. Conversion(打包指令)
| packsswb | __m64 _mm_packs_pi16 (__m64 a, __m64 b) __m64 _m_packsswb (__m64 a, __m64 b) | 將壓縮16位字整數(shù)a和bpack成8位字節(jié)整數(shù)使用有符號(hào)飽和運(yùn)算,保存到結(jié)果中 | 
| packssdw | __m64 _mm_packs_pi32 (__m64 a, __m64 b) __m64 _m_packssdw (__m64 a, __m64 b) | 將壓縮32位雙字整數(shù)a和b pack成16位字整數(shù)使用有符號(hào)飽和運(yùn)算,保存到結(jié)果中 | 
| packuswb | __m64 _mm_packs_pu16 (__m64 a, __m64 b) __m64 _m_packuswb (__m64 a, __m64 b) | 將壓縮16位字整數(shù)a和b pack成8位字節(jié)整數(shù)使用無(wú)符號(hào)飽和運(yùn)算,保存到結(jié)果中 | 
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數(shù)據(jù)的高一半位數(shù)數(shù)據(jù)(32位)保存到結(jié)果中,具體保存方式參考如下描述 | 
| 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(邏輯運(yùn)算)
| pand | ||
| pandn | ||
| por | ||
| pxor | 
7. Shift(移位)
| psllw | ||
| pslld | ||
| psllq | ||
| psrlw | ||
| psrld | ||
| psrlq | ||
| psraw | ||
| psrad | 
8. EMMS
| emms | void _m_empty (void)void _mm_empty (void) | 使用 EMMS 命令與空容器以容納新目錄 | 
EMMS使用方法: 
 1. 如果下一條命令是浮點(diǎn)命令,請(qǐng)?jiān)贛MX指令后使用_mm_empty(例如在進(jìn)行float,double和long double 類型的計(jì)算前) 
 2. 當(dāng)寄存器中不存在MMX寄存時(shí),不要使用EMMS指令。如果下一個(gè)命令使用MMX寄存器,使用EMMS沒有好處(不會(huì)進(jìn)行優(yōu)化) 
 3. 
總結(jié)
以上是生活随笔為你收集整理的SIMD——MMX指令集介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: SIMD——MMX指令的溢出处理
- 下一篇: 服务器定时开机设置方法
