目录
0.0 背景及学习资源
AArch64是ARMv8 架构的一种执行状态。ARMv8-A 是首款64 位架构的ARM 处理器,是移动手机端使用的CPU。
两种主要执行状态:
(PS:一直在思考如何在aarch64状态下执行v7的代码)
- AArch64 - 64 位执行状态,包括该状态的异常模型、内存模型、程序员模型和指令集支持
- AArch32 - 32 位执行状态,包括该状态的异常模型、内存模型、程序员模型和指令集支持
1.0 寄存器
系统运行在64位状态下的时候名字叫Xn,运行在32位的时候就叫Wn; 寄存器的位数为64bit。****注意作为函数参数的传递的时候,X0-X7用来保存函数的前8个参数(v7是r0-r3),剩下的利用存储器进行加载
(PS:如何使用浮点寄存器和通用寄存器之间相互进行数据的传输)
- 通用寄存器(X0-X30)
- 浮点寄存器
- zero寄存器
2.0 汇编操作指令
3.0 Neon
使用ARM的SIMD指令的方法是在添加编译选项-mfpu=neon,在ARM v8a架构下使用NEON就不要像ARM v7a一样的显示调用了,直接指明我要用的是D寄存器。
在Armv8中是不需要对编译选项进行选择,直接利用添加arm_neon.h就可以调用Neon的相关函数。
(PS:armv8的时候到底要不要添加编译选项)
SIMD:Single Instruction Multiple Data,单指令多数据流
SISD:Single Instruction Single Data, 单指令单数据
3.1 Neon 寄存器
ARMv7a 有32个64位的D寄存器[D0-D31], 16个128位的Q寄存器 [Q0-Q15] ,一个Q对应2个D(2个D公用Q的高64位和低64位)。
ARMv8有32个128位的V寄存器,相似的,我们同样可以看成是32个32位的S寄存器或者32个64位的D寄存器。
3.2常用的指令
饱和指令
uint32x2_t vqadd_u32 (uint32x2_t, uint32x2_t)
指令格式: vqadd.u32 d0, d0, d0
数据移动和加载
VMOV:
vmov d0, r0, r1:将r1的内容送到d0到低半部分,r0的内容送到d0到高半部分
vmov r0, r1, d0:将d0的低半部分送到r0,d0的高半部分内容送到r1
一个arm寄存器和d之间
vmov.U32 d0[0], r0:将r0的内容送到d0[0]中,d0[0]指d0到低32位
vmov.U32 r0, d0[0]:将d0[0]的内容送到r0中
立即数:
vmov.U16 d0, #1:将立即数1赋值给d0的每个16位
vmov.U32 q0, #1:将立即数1赋值给q0的每个32位
长指令:VMOVL:d赋值给q
vmovl.U16 q0, d0:将d0的每个16位数据赋值到q0的每个32位数据中
窄指令:VMOVN:q赋值给d
vmovn.I32 d0, q0:将q0的每32位数据赋值到q0的每16位数据中
饱和指令:VQMOVN等,饱和到指定的数据类型
vqmovun.S32 d0, q0:将q0到每个32位移动到d0中到每个16位中,范围是0-65535
资料/文档:
【1】《Programmer’s Guide》
参考文献
【1】ARM v7a和v8a对NEON的使用区别
https://www.jianshu.com/p/0f59c019e322
【2】 ART世界探险(5) - 计算指令
https://yq.aliyun.com/articles/57985?spm=a2c4e.11153940.blogcont57934.9.4a251ce1oxxKxE
【3】 官网指南********
https://developer.arm.com/technologies/neon
【4】GCC支持的ARM NEON 内联SIMD Intrinsics***
https://blog.csdn.net/yuyin86/article/details/18335063?locationNum=11&fps=1
【5】ARM和NEON指令
https://blog.csdn.net/chshplp_liaoping/article/details/12752749