ARMv8 浮点及NEON指令集
通常,每个NEON指令都会导致n个指令并行执行!
向量寄存器
32个128位寄存器
32个64位寄存器
所有的寄存器都可以在任意时间被访问,且访问者不需要显式地在两种表示之间切换,指令会说明是使用64位还是128位寄存器形式。
浮点寄存器
标量与NEON
标量就相当于是向量中的某一个lane,通过index获取。MOV V0.B[3], W0
只会把w0的第一个字节拷到v0寄存器的第四个lane:
乘法指令只允许16-bit和32-bit标量,而且只能使用前128个标量。即16-bit只能使用0~15号寄存器,32-bit可以使用所有寄存器(因为32个32位刚好是128个)
浮点参数
AArch64 NEON指令形式
主要是通过和ARMv7 NEON对比来说明ARMv8 NEON的形式
V前缀被移除
ARMv8 NEON指令具有完全统一的形式,不管是整数、浮点数还是向量。具体执行操作也是完全根据每个指令的不同和不同。
第一个是32位整数的加法指令;第二个是64位整数加法;第三个是浮点标量加法;最后是向量加法指令。
S U F P 四个前缀可以被添加用来说明是有符号、无符号、浮点数、多项式中的某一种数据类型
SADD x0, x0, x1
UADD x0, x0, x1
FADD D0, D0, D1
PADD v0.16B, v0.16B, v1.16B
向量的组织(元素size和数量)都是用向量寄存器的描述来区分的
ADD Vd.T, Vn.T, Vm.T
其中Vd Vn Vm都是寄存器的名字,T是寄存器的组织形式,可以是8B,16B,8H,4H,4S,2S,2D,D等。
如果是要对2个double进行向量加法:ADD V0.2D, V0.2D, V1.2D
正常、长、宽、窄、饱和指令
-
Normal指令,对相同类型的数据进行操作,返回结果的数据类型与源类型相同
-
长指令,使用L作为后缀,结果数据的位数是源数据位数的两倍
SADDL V0.4S, V1.4H, V2.4H
-
Wide宽指令,对一个双字数据和一个单字数据进行操作,结果将都是双字数据,使用W作为后缀
SADDW V0.4S, V1.4H, V2.4S
-
Narrow指令,操作两个四字向量,得到双字向量,结果数据是源数据的一半长,使用N作为后缀
SUBHN V0.4H, V1.4S, V2.4S
-
有符号和无符号的饱和运算(SQ 和 UQ),比如加法 SQADD 和 UQADD分别表示有符号饱和加以及无符号饱和加,如果结构数据超过了最大最小界限,饱和运算会使得结果不过超过最大或最小
SQADD V0.16B, V0.16B, V1.16B
后缀P,表示分对操作
比如ADDP V0.4S, V1.4S, V2.4S
后缀V,表示跨所有lane的操作
比如 ADDV S0, V1.4S
后缀2,表示对高位的那一半进行操作,可以用在Wide Narrow Lengthing等指令后
- 宽指令
- narrow 指令
- Lengthing 指令
上一篇: maven 常用指令集
推荐阅读