2021—研一学习笔记 day12

2021-3-30 第十二天

指令集学习

Intel->指令集->MMX

网址:
https://software.intel.com/sites/landingpage/IntrinsicsGuide/#techs=MMX&cats=Arithmetic&expand=210,132

MMX指令集学习
(重点看 加载、导出、逻辑运算、移位运算、shuffle洗牌指令)

头文件:#include <mmintrin.h>
__m64的定义为:

typedef union __declspec(intrin_type) _CRT_ALIGN(8) __m64 
{  
	    unsigned __int64    m64_u64;  
	    float               m64_f32[2];  
	    __int8              m64_i8[8];  
	    __int16             m64_i16[4];  
	    __int32             m64_i32[2];      
	    __int64             m64_i64;  
	    unsigned __int8     m64_u8[8];  
	    unsigned __int16    m64_u16[4];  
	    unsigned __int32    m64_u32[2];  
} __m64;  

正常指令:生成大小相同且类型通常与操作数向量相同的结果向量
宽指令:一个双字操作数和一个四字操作数执行运算,生成四字向量结果
窄指令:四字向量操作数执行运算,生成双字向量结果(减半)
饱和指令:当超过数据类型指定到范围则自动限制在该范围内
长指令:对双字向量操作数执行运算,生成四字向量结果(加倍)


//1、Application-Targeted 以应用为目标
2、Arithmetic 算术
1)__m64 _mm_add_pi16(__m64 a, __m64 b)

FOR j := 0 to 3
	i := j*16
	dst[i+15:i] := a[i+15:i] + b[i+15:i]
ENDFOR

2)__m64 _mm_add_pi32(__m64 a, __m64 b)

FOR j := 0 to 1
	i := j*32
	dst[i+31:i] := a[i+31:i] + b[i+31:i]
ENDFOR

3)__m64 _mm_add_pi8(__m64 a, __m64 b)

FOR j := 0 to 7
	i := j*8
	dst[i+7:i] := a[i+7:i] + b[i+7:i]
ENDFOR

4)__m64 _mm_adds_pi16(__m64 a, __m64 b)
注:saturation(add) 饱和(加法)指令:如果结果超过255,则就赋为255

FOR j := 0 to 3
	i := j*16
	dst[i+15:i] := Saturate16( a[i+15:i] + b[i+15:i] )
ENDFOR
  1. __m64 _mm_adds_pi8(__m64 a, __m64 b)
FOR j := 0 to 7
	i := j*8
	dst[i+7:i] := Saturate8( a[i+7:i] + b[i+7:i] )
ENDFOR
  1. __m64 _mm_adds_pu16(__m64 a, __m64 b)
FOR j := 0 to 3
	i := j*16
	dst[i+15:i] := SaturateU16( a[i+15:i] + b[i+15:i] )
ENDFOR
  1. __m64 _mm_adds_pu8(__m64 a, __m64 b)
FOR j := 0 to 7
	i := j*8
	dst[i+7:i] := SaturateU8( a[i+7:i] + b[i+7:i] )
ENDFOR
  1. __m64 _mm_madd_pi16(__m64 a, __m64 b)
FOR j := 0 to 1
	i := j*32
	dst[i+31:i] := SignExtend32(a[i+31:i+16]*b[i+31:i+16]) + SignExtend32(a[i+15:i]*b[i+15:i])
ENDFOR

#SignExtend32:32位符合扩展

  1. __m64 _mm_mulhi_pi16(__m64 a, __m64 b)
FOR j := 0 to 3
	i := j*16
	tmp[31:0] := SignExtend32(a[i+15:i]) * SignExtend32(b[i+15:i])
	dst[i+15:i] := tmp[31:16]
ENDFOR
  1. __m64 _mm_mullo_pi16(__m64 a, __m64 b)
FOR j := 0 to 3
	i := j*16
	tmp[31:0] := a[i+15:i] * b[i+15:i]
	dst[i+15:i] := tmp[15:0]
ENDFOR
  1. __m64 _m_paddb(__m64 a, __m64 b) 同3)
  2. __m64 _m_paddd(__m64 a, __m64 b) 同2)
  3. __m64 _m_paddsb(__m64 a, __m64 b) 同5)
  4. __m64 _m_paddsw(__m64 a, __m64 b) 同4)
    15)__m64 _m_paddusb(__m64 a, __m64 b) 同7)
  5. __m64 _m_paddusw(__m64 a, __m64 b) 同6)
  6. __m64 _m_paddw(__m64 a, __m64 b) 同1)
  7. __m64 _m_pmaddwd(__m64 a, __m64 b) 同8)
  8. __m64 _m_pmulhw(__m64 a, __m64 b) 同9)
  9. __m64 _m_pmullw(__m64 a, __m64 b) 同10)
  10. __m64 _m_psubb(__m64 a, __m64 b)
  11. __m64 _m_psubd(__m64 a, __m64 b)
  12. __m64 _m_psubsb(__m64 a, __m64 b)
  13. __m64 _m_psubsw(__m64 a, __m64 b)
  14. __m64 _m_psubusb(__m64 a, __m64 b)
  15. __m64 _m_psubusw(__m64 a, __m64 b)
  16. __m64 _m_psubw(__m64 a, __m64 b)
    。。。

总结:
b:byte–8bit
w:word–16bit
d:double–32bit

u:unsigned–无符号数
s:saturate–饱和指令
p:packed–压缩
hi:high–高位
lo:low–低位
wd:word double–字转双字
每个指令,两种格式 ①_mm_ ②_m_p
例:
_mm_add_pi16 _m_paddw
_mm_mulhi_pi16 _m_pmulhw
_mm_adds_pu8 _m_paddusb
_mm_madd_pi16 _m_pmaddwd
//
//3、Bit Manipulation 位操作
//4、Cast
5、Compare 比较
1)__m64 _mm_cmpeq_pi16 (__m64 a, __m64 b)

FOR j := 0 to 3
	i := j*16
	dst[i+15:i] := ( a[i+15:i] == b[i+15:i] ) ? 0xFFFF : 0
ENDFOR
  1. __m64 _mm_cmpgt_pi32 (__m64 a, __m64 b)
  2. __m64 _m_pcmpeqb (__m64 a, __m64 b)

总结:
eq:equip 等于
gt:greater 大于

6、Convert 转变

  1. __int64 _mm_cvtm64_si64 (__m64 a)
dst[63:0] := a[63:0]
  1. __m64 _mm_cvtsi32_si64 (int a)
dst[31:0] := a[31:0]
dst[63:32] := 0
  1. __m64 _mm_cvtsi64_m64 (__int64 a)
dst[63:0] := a[63:0]
  1. int _mm_cvtsi64_si32(__m64 a)
dst[31:0] := a[31:0]
  1. __m64 _m_from_int(int a)
  2. __m64 _m_from_int64(__int64 a)
  3. int _m_to_int(__m64 a)
  4. __int64 _m_to_int64(__m64 a)

//7、Cryptography 密码学
//8、Elementary Math 基本数学函数


函数
1、General Support
1)void _m_empty (void)
2)void _mm_empty (void)

//2、Load 加载
3、Logical 逻辑运算
1)__m64 _mm_and_si64 (__m64 a, __m64 b)

dst[63:0] := (a[63:0] AND b[63:0])

2)__m64 _mm_andnot_si64 (__m64 a, __m64 b)

dst[63:0] := ((NOT a[63:0]) AND b[63:0])

3)__m64 _mm_or_si64 (__m64 a, __m64 b)

dst[63:0] := (a[63:0] OR b[63:0])

4)__m64 _m_pand (__m64 a, __m64 b) 同1)
5)__m64 _m_pandn (__m64 a, __m64 b) 同2)
6)__m64 _m_por (__m64 a, __m64 b) 同3)
7)__m64 _m_pxor (__m64 a, __m64 b)

dst[63:0] := (a[63:0] XOR b[63:0])

8)__m64 _mm_xor_si64 (__m64 a, __m64 b) 同7)

//4、Mask
5、Miscellaneous

  1. __m64 _mm_packs_pi16 (__m64 a, __m64 b)
    注:字转字节(符号饱和)
dst[7:0] := Saturate8(a[15:0])
dst[15:8] := Saturate8(a[31:16])
dst[23:16] := Saturate8(a[47:32])
dst[31:24] := Saturate8(a[63:48])
dst[39:32] := Saturate8(b[15:0])
dst[47:40] := Saturate8(b[31:16])
dst[55:48] := Saturate8(b[47:32])
dst[63:56] := Saturate8(b[63:48])
  1. __m64 _mm_packs_pi32 双字转字(符号饱和)
dst[15:0] := Saturate16(a[31:0])
dst[31:16] := Saturate16(a[63:32])
dst[47:32] := Saturate16(b[31:0])
dst[63:48] := Saturate16(b[63:32])
  1. __m64 _mm_packs_pu16 无符号字转字节(符号饱和)
    4)__m64 _m_packssdw (__m64 a, __m64 b) 同2)
  2. __m64 _m_packsswb (__m64 a, __m64 b) 同1)
  3. __m64 _m_packuswb (__m64 a, __m64 b) 同3)


//6、Move 移动
//7、OS-Targeted 以操作系统为目标
//8、Probability/Statistics 概率/统计
//9、Random 随机
10、Set 设置
1)__m64 _mm_set_pi16 (short e3, short e2, short e1, short e0)

dst[15:0] := e0
dst[31:16] := e1
dst[47:32] := e2
dst[63:48] := e3
  1. __m64 _mm_set_pi32 (int e1, int e0)
dst[31:0] := e0
dst[63:32] := e1
  1. __m64 _mm_set_pi8 (char e7, char e6, …, char e0)
dst[7:0] := e0
dst[15:8] := e1
dst[23:16] := e2
dst[31:24] := e3
dst[39:32] := e4
dst[47:40] := e5
dst[55:48] := e6
dst[63:56] := e7
  1. __m64 _mm_set1_pi16 (short a)
FOR j := 0 to 3
	i := j*16
	dst[i+15:i] := a[15:0]
ENDFOR
  1. __m64 _mm_set1_pi32 (int a)
FOR j := 0 to 1
	i := j*32
	dst[i+31:i] := a[31:0]
ENDFOR
  1. __m64 _mm_set1_pi8 (char a)
FOR j := 0 to 7
	i := j*8
	dst[i+7:i] := a[7:0]
ENDFOR
  1. __m64 _mm_setr_pi16 (short e3, short e2, short e1, short e0)
    注:与set指令赋值顺序相反
dst[15:0] := e3
dst[31:16] := e2
dst[47:32] := e1
dst[63:48] := e0
  1. __m64 _mm_setr_pi32 (int e1, int e0)
dst[31:0] := e1
dst[63:32] := e0
  1. __m64 _mm_setr_pi8 (char e7, char e6, …, char e0)
dst[7:0] := e7
dst[15:8] := e6
dst[23:16] := e5
dst[31:24] := e4
dst[39:32] := e3
dst[47:40] := e2
dst[55:48] := e1
dst[63:56] := e0
  1. __m64 _mm_setzero_pi64 (void)
    #全部赋值为0
dst[MAX:0] := 0

11、Shift 转移

_m_ps(l/r)l(d/q/w)

  1. __m64 _m_pslld (__m64 a, __m64 count)
    #左移(32bit寄存器)
FOR j := 0 to 1
	i := j*32
	IF count[63:0] > 31
		dst[i+31:i] := 0
	ELSE
		dst[i+31:i] := ZeroExtend32(a[i+31:i] << count[63:0])
	FI

ENDFOR
2) __m64 _m_pslldi (__m64 a, int imm8)
3) __m64 _m_psllq (__m64 a, __m64 count)
#左移(64bit寄存器)

IF count[63:0] > 63
	dst[63:0] := 0
ELSE
	dst[63:0] := ZeroExtend64(a[63:0] << count[63:0])
FI
  1. __m64 _m_psllqi (__m64 a, int imm8)
  2. __m64 _m_psllw (__m64 a, __m64 count)
  3. __m64 _m_psllwi (__m64 a, int imm8)

_m_psr(a/l)(d/w/q)
#a与l的填充方式不同,a为。。,l为填0
7) __m64 _m_psrad (__m64 a, __m64 count)

FOR j := 0 to 1
	i := j*32
	IF count[63:0] > 31
		dst[i+31:i] := (a[i+31] ? 0xFFFFFFFF : 0x0)
	ELSE
		dst[i+31:i] := SignExtend32(a[i+31:i] >> count[63:0])
	FI
ENDFOR

总结:
①每个指令,两种格式:m mm
例:_m_pslld _mm_sll_pi32
_m_psraw _mm_sra_pi16
②l代表左移,r代表右移
③左移均为全0填充,右移有两种填充方式
ra为全1填充(SignExtend)符号扩展
rl为全0填充(ZeroExtend)无符号扩展

//12、Special Math Functions 特殊数学功能
//13、Store
//14、String Compare 字符串比较
15、Swizzle

  1. __m64 _m_punpckhbw (__m64 a, __m64 b)
    #每8bit一交替,使用a、b的高位
DEFINE 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])
  1. __m64 _m_punpckhdq (__m64 a, __m64 b)
    #每32bit一交替,使用a、b的高位
dst[31:0] := a[63:32]
dst[63:32] := b[63:32]

  1. __m64 _m_punpckhwd (__m64 a, __m64 b)
    #每16bit一交替,使用a、b的高位
DEFINE INTERLEAVE_HIGH_WORDS(src1[63:0], src2[63:0]) {
	dst[15:0] := src1[47:32]
	dst[31:16] := src2[47:32]
	dst[47:32] := src1[63:48]
	dst[63:48] := src2[63:48]
	RETURN dst[63:0]
}
dst[63:0] := INTERLEAVE_HIGH_WORDS(a[63:0], b[63:0])

  1. __m64 _m_punpcklbw (__m64 a, __m64 b)
    #每8bit一交替,使用a、b的低位
  2. __m64 _m_punpckldq (__m64 a, __m64 b)
    #每32bit一交替,使用a、b的低位
  3. __m64 _m_punpcklwd (__m64 a, __m64 b)
    #每16bit一交替,使用a、b的低位
  4. __m64 _mm_unpackhi_pi16 (__m64 a, __m64 b) 同1)
  5. __m64 _mm_unpackhi_pi32 (__m64 a, __m64 b) 同2)
  6. __m64 _mm_unpackhi_pi8 (__m64 a, __m64 b) 同3)
  7. __m64 _mm_unpacklo_pi16 (__m64 a, __m64 b) 同4)
  8. __m64 _mm_unpacklo_pi32 (__m64 a, __m64 b) 同5)
  9. __m64 _mm_unpacklo_pi8 (__m64 a, __m64 b) 同6)

//16、Trigonometry 三角

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值