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 寄存器传值来指定指针的对齐,通常用于加速内存的访问。

其他存取指令

  • VLDRVSTR
    用于向单个寄存器读写 64 bits 数据。
  • VLDMVSTM
    用于向多个寄存器读写 64 bits 数据。通常用于从栈中存取数据。