NEON的Registers, vectors, lanes and elements
NEON指令和浮点指令使用相同的寄存器文件,称之为“NEON和浮点寄存器文件”。
它跟ARM core 寄存器文件完全区分开。NEON和浮点寄存器文件是一组可以作为32-bit、64-bit或128-bit的寄存器来访问。对于一个指令,哪个寄存器是可用的依赖于它是一个NEON指令还是一个VFP指令。本文把NEON和浮点寄存器作为NEON寄存器。一些VFP和NEON指令在通用寄存器和NEON寄存器之间移动数据,或使用ARM通用寄存器来寻址内存。
NEON寄存器的内存是相同数据类型的元素向量。一个向量被分割成通道(lanes),每个通道包含一个数值,称之为“元素”。
通常,每个NEON指令会并行执行n个操作,这里的n是输入向量分割成的通道的个数。每个操作包含在通道内。不会考虑到一个通道到另一个通道间的进位或溢出。
一个NEON向量的通道的个数依赖于向量的大小和向量中的数值元素:
元素排序
图1-1 显示了向量中的元素的排序,从最低位开始。这意味着,元素0使用了寄存器的最低有效位。
图 1-1 元素与通道
图 1-2显示了 VADD.I16 Q0, Q1, Q2 指令是如何并行执行Q1和Q2内的8x16-bit整数add操作,把结果保存到Q0中。
图 1-2 8 way 16-bit integer add operation
Register overlap
图 1-3 显示NEON和浮点寄存器文件,寄存器怎样重叠的。
NEON单元把寄存器文件看作:
D寄存器的映射为:
图 1-3 NEON and floating-point register file
所有这些寄存器在任何时候都能访问。软件并不需要精确地在它们之间切换,因为使用的指令会决定合适的view。
在图 1-4 中,S\D和Q寄存器是相同寄存器Q0的不同view。:
图 1-4 Register overlap
Scalar data
标量数据是指一个单一数值,而不是一个包含多个值的向量。一些NEON指令使用一个标量操作符。一个寄存器内的标量可以通过到向量的index来访问。用于访问向量的单个元素的数组标识是 Dm[x]或 Qm[x],其中, x是向量 Dm或 Qm的索引。
指令 VMOV.8 D0[3], R3 移动寄存器R3中的最低有效字节到寄存器D0的第四个字节中。
图 1-5 Moving a scalar to a lane
NEON标量可以是8-bit、16-bit、32-bit或64-bit值。与乘法指令不同,访问标量的指令可以访问寄存器文件中的任何元素。
乘法指令只能允许16-bit或32-bit标量,并且只能访问寄存器文件中的前32个标量: