ARM Neon 编程(一):读取与存储
以下基本摘自Coding for NEON - Part 1: Load and Stores
示例
假设当前有 24 bits RGB 图像,对该图像要对其中部分通道做一定操作,如交换 R 通道和 B 通道。由于数据在内存中的排布为 R,G,B 单通道以此交错排布,所以载入寄存器后还要借助一些操作分离三个通道。
Neon 读取指令可以在载入寄存器时就完成分选操作,上面分离三通道的 Neon 指令如下
1 | VLD3.8 {d0, d1, d2} [r0] |
这样一条指令就可以将 RGB 三个通道分别装入到 d0, d1, d2 中。源地址由 r0 arm 寄存器指定。
指令语义
1 | VLD3.8 {d0, d1, d2} [r0]; |
上面这行 Neon 指令语义分以下几个部分
- VLD
指令助记符VLD,VST,表明这是读取指令还是存储指令 - 3
分选模式,表示相对应元素之间的间隔 - 8
元素类型,表示访问元素的 bits 数 - {d0, d1, d2}
Neon 寄存器列表,对列表中的寄存器进行读或写操作。最多可以有 4 个,也分选模式决定. - [r0]
arm 地址寄存器,指定源数据地址,可以在访问后更新。
分选模式(interleave pattern)
Neon 指令能够读取,存储并且分选包含有 1 到 4 个相同大小元素的结构,元素种类为 Neon 支持的如 8, 16, 32 bits 类型数据
- VLD1
无分选模式读取,从内存读取 1 到 4 个寄存器大小数据。通常用于处理非交错数据(non-interleaveing data) - VLD2
分选模式为 3,从内存读入 2 到 4 个寄存器大小。奇数位置和偶数位置元素装入不同寄存器中。通常用于分离双通道数据,如左右立体声。 - VLD3
分选模式为 3,读入 3 个寄存器大小数据并分选通道。通常用于分离RGB图像的通道。 - VLD4
分选模式为 4, 读入 4 个寄存器大小数据并分选通道。通常用于分离ARGB图像的通道。
以上这些模式都有对应的存储指令,可以在写入内存前就完成通道的分选。
元素类型(element type)
元素类型通常表示为 8 bits, 16 bits, 还是 32 bits. 影响寄存器装入的元素个数和分选步长。
寻址模式
结构化存取指令支持 3 中寻址方式(其实没看懂他的语法格式)
- Register:
[ {, :}]
最简单的格式,将对指定的地址进行读写操作。 - Register With increment after:
[ {, :}]!
在读写操作后会更新指针,以准备下一次的读写。指针增长的值等于指令读写的字节数. - Register with post-index:
[ {, :}] ,
在读写操作后,指针会更新,会加上Rm寄存器的值。通常用于读写间距固定的一组数据,如图像中的一列。
使用可选 : 参数,向 Rn 寄存器传值来指定指针的对齐,通常用于加速内存的访问。
其他存取指令
VLDR和VSTR
用于向单个寄存器读写 64 bits 数据。VLDM和VSTM
用于向多个寄存器读写 64 bits 数据。通常用于从栈中存取数据。