在arm neon的指令集中,大多数都是单词的缩写加一些特殊的前后缀修饰符。
正常指令q
可以对任一向量类型执行运算,并生成大小相同且类型与操作数向量相同的结果向量。
长指令l
长指令对双字向量操作数执行运算,并生成四字向量结果。所生成的元素通常是操作数元素宽度的两倍,并属于同一类型。
宽指令w
宽指令对一个双字向量操作数和一个四字向量操作数执行运算。所生成的元素和第一个操作数的元素是第二个操作数元素宽度的两倍。
窄指令n
窄指令对四字向量操作数执行运算,并生成双字向量结果。 所生成的元素通常是操作数元素宽度的一半。
饱和指令q
在V与指令助记符之间的使用q前缀可以指定饱和指令。饱和指令限定了各种类型的数据范围。
neon寄存器
有16个128位的四字寄存器Q0-Q15
,32个64位的双字寄存器D0-D31
,两个寄存器是重叠的。(每32位一个字)
对于指令最前面的v表示是向量操作。
neon支持的主要操作
助记符 | 含义 |
---|---|
add | 加法 |
sub | 减法 |
mul | 乘法 |
mla | 乘加 |
mls | 乘减 |
ceq | 比较 == |
cge | 比较 >= |
cle | 比较 <= |
cgt | 比较 > |
clt | 比较 < |
max | 最大值 |
min | 最小值 |
shl | 左移位 |
shr | 右移位 |
abs | 求绝对值 |
neg | 取反 |
mvn | 按位取反 |
and | 与运算 |
orr | 或运算 |
eor | 异或运算 |
get | 取值 |
set | 赋值 |
dup | 构造一个向量,并进行初始化 |
combine | 合并操作,将两个向量进行合并 |
mov | 改变数据类型和数据范围 |
zip | 压缩操作 |
uzp | 解压操作 |
ld1 | 加载数据,从给定的buffer指针中拷贝数据 |
st1 | 拷贝数据,将数据拷贝到指定的buffer中 |
tst | 进行与运算之后,判断是否等于0 |
abd | 两个向量相减之后的绝对值 |
学习资源
https://people.xiph.org/~tterribe/daala/neon_tutorial.pdf
https://elinux.org/images/4/40/Elc2011_anderson_arm.pdf
https://community.arm.com/processors/b/blog/posts/coding-for-neon—part-1-load-and-stores
https://community.arm.com/processors/b/blog/posts/coding-for-neon—part-2-dealing-with-leftovers
https://community.arm.com/processors/b/blog/posts/coding-for-neon—part-3-matrix-multiplication
https://github.com/thenifty/neon-guide
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0073a/IHI0073A_arm_neon_intrinsics_ref.pdf?resultof=%22vmovq_n_f32%22%20
参考文献:
https://blog.csdn.net/xiongtiancheng/article/details/77103810