NEON的Registers, vectors, lanes and elements
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向量的通道的个数依赖于向量的大小和向量中的数值元素:
- 64-bitNEON向量可以包含:
- 8x8-bit
- 4x16-bit
- 2x32-bit
- 1x64-bit
- 128-bitNEON向量可以包含:
- 16x8-bit
- 8x16-bit
- 4x32-bit
- 2x64-bit
元素排序
图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单元把寄存器文件看作:
- 16个 128-bit Q,或 4字,寄存器,Q0-Q15。
- 32个64-bit D,或双字,寄存器,D0-D31。(16个 64-bit D 寄存器VFPv3-D16)。
D寄存器的映射为:
- D<2n>映射为Q<n>的低半部分;
- D<2n+1>映射为Q<n>的高半部分;
- Q和D寄存的结合
- NEON单元寄存器不能直接访问一个32-bit VFP S寄存器。见NEON和浮点寄存器文件的VFP 角度。
- S<2n>映射到 D<n>的低半部分;
- S<2n+1>映射到D<n>的高半部分。
图 1-3 NEON and floating-point register file
所有这些寄存器在任何时候都能访问。软件并不需要精确地在它们之间切换,因为使用的指令会决定合适的view。
在图 1-4 中,S\D和Q寄存器是相同寄存器Q0的不同view。:
- NEON单元可以把Q0作为一个128-bit寄存器访问。
- NEON单元可以把Q0作为2个连续的64-bit寄存器D0和D1来访问。
- NEON单元不能单独把Q0作为32-bit S 寄存器访问。如果存在VFP单元,可以把它当作S0、S1、S2和S3来访问。
图 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个标量:
- 16-bit标量限制在寄存器 D0[x]-D7[x],x的范围是0到3。
- 32-bit标量限制在寄存器 D0[x]-D15[x],x的范围是0到1.