学习Armv8架构时,对部分内容的翻译和整理
Armv8体系架构(1)
Armv8体系架构(2)
Armv8体系架构(3)
1. 高级SIMD和浮点支持
在AArch32状态下,对SIMD&FP寄存器进行操作的SIMD指令始终被描述为高级SIMD指令,以便区别于基本指令集中的SIMD指令,这些指令对32位通用寄存器进行操作。
A64指令集不提供任何对通用寄存器进行操作的SIMD指令,因此一些AArch64状态描述使用SIMD作为高级SIMD的同义词。
Armv8可以支持以下级别的高级SIMD和浮点指令:
(1) 完整的SIMD和浮点支持,无异常捕获;
(2) 带有异常捕获的完整SIMD和浮点支持;
(3) 不支持浮点或SIMD。(仅针对特定的场景)
Note: 所有支持具有丰富应用环境的标准操作系统的系统都提供了对高级SIMD和浮点的硬件支持。
SIMD指令提供打包的单指令多数据(SIMD)和单元素标量操作,并支持:
(1)AArch64状态下的单精度和双精度算术;
(2)仅在AArch32状态下的单精度算术;
(3)当Armv8.2-FP16实施时,AArch64和AArch32状态支持半精度算术。
AArch64状态SIMD中的浮点支持符合IEEE754-2008,符合:
(1)可配置的舍入模式;
(2)可配置的默认NaN行为;
(3)可配置的清零行为。
使用AArch32高级SIMD指令的浮点计算与Armv7保持不变。 A32和R32高级SIMD浮点始终使用Arm标准浮点运算并执行IEEE754浮点运算,但具有如下限制:
(1)非规范化数字被刷新为零;
(2)仅支持默认NaN;
(3)未捕获的浮点异常处理用于所有浮点异常。
如果支持异常捕获,则可以在不捕获的情况下处理浮点异常,例如溢出或除以零。这适用于SIMD和浮点运算。以这种方式处理时,浮点异常会导致累积状态寄存器位设置为1,并且操作会产生默认结果。
在AArch64状态下,以下寄存器控制浮点运算并返回浮点状态信息:
- 浮点控制寄存器FPCR控制:
a. 适用的半精度格式,FPCR.AHP位;
b. 默认NaN行为,FPCR.DN位;
c. 清零行为,FPCR.{FZ, FZ16}位。如果Armv8.2-FP16没有实现,FPCR.FZ16为RES0;
d. 舍入模式支持,FPCR.Rmode字段;
e. Len和Stride字段与AArch32状态下的执行相关联,仅支持从AArch64状态进行上下文保存和恢复;
f. 浮点异常陷阱控制,FPCR.{IDE, IXE, UFE, OFE, DZE, IOE}位。 - 浮点状态寄存器FPSR提供:
a. 累积浮点异常标志、FPSR.{IDC, IXC, UFC, OFC, DZC, IOC, 和QC};
b. AArch32浮点比较标志{N, Z, C, V}。AArch32浮点,则这些位为RES0;
Note: 在AArch64状态下,进程状态标志PSTA TE.{N, Z, C, V}用于所有数据处理和任何相关的条件执行。
AArch32状态提供单个浮点状态和控制寄存器FPSCR,结合了FPCR和FPSR字段。
1.1 高级SIMD和浮点指令支持
- 加载和存储单个元素和多个元素的向量;
- 整数和浮点数据类型的单个和多个元素的数据处理;
- 可实现复数运算(在Armv8.3-CompNum中);
- 不同精度级别之间的转换;
- 浮点、定点整数和整数数据类型之间的转换;
- 浮点舍入;
1.2 Arm标准浮点输入和输出值
Armv8提供完整的IEEE 754浮点算术支持。在AArch32状态下,使用高级SIMD指令执行的浮点运算仅限于Arm标准浮点运算,而与FPSCR中的舍入模式无关。与AArch32不同,AArch64 SIMD浮点运算是使用FPCR选择的舍入模式执行的。
Arm标准浮点运算支持IEEE 754浮点标准定义的以下输入格式:
- 0
- 标准化数字
- 非规范化数字在浮点运算之前被刷新为0
- NaNs
- 无穷大
Arm标准浮点运算支持IEEE 754浮点标准定义的以下输出结果格式:
- 0
- 标准化数字
- 小于最小归一化数的结果被刷新为0
- 无穷大
1.3 清零模式
在涉及非规范化数字和下溢异常的计算时,浮点处理的性能可能会降低。在许多算法中,可以通过用零替换非规范化操作数和中间结果来恢复这种性能,而不会显著影响最终结果的准确性。Arm浮点实现允许将清零模式用于不同的浮点格式, 如下所示:
AArch64状态:
1. 如果FPCR.FZ=1,清零模式用于所有指令的所有单精度和双精度输入和输出。
2. 如果FPCR.FZ16=1,则清零模式用于浮点指令的所有半精度输入和输出。除了:
a. 半精度和单精度数字之间的转换;
b. 半精度和双精度数字之间的转换。
AArch32状态:
1. 如果FPSCR.FZ=0,则清零模式用于所有高级SIMD浮点指令的所有单精度和双精度输入和输出;
2. 如果FPSCR.FZ=1,则清零模式用于所有指令的所有单精度和双精度输入和输出。
3. 如果FPSCR.FZ16==1,则清零模式用于浮点指令的所有半精度输入和输出,除了:
a. 半精度和单精度数字之间的转换;
b. 半精度和双精度数字之间的转换。
如果在单精度或双精度输入上使用清零模式:
- 浮点运算的所有输入在其表示的精度中都是非规范化的数字,都被视为零,与输入具有相同的符号,并生成非规范化浮点异常。
- 除输入非正规外的所有浮点异常的发生是使用被此机制视为零的输入值确定的。
- 在AArch32状态下,FPSCR包含一个累积异常位FPSCR.IDC和可选的陷阱启用位FPSCR.IDE,对应于输入非正规浮点异常。
- 在AArch64状态下,FPSR包含一个累积异常位FPSR.IDC和可选的陷阱启用位FPCR.IDE,对应于输入非正规浮点异常。
如果在半精度输入上使用清零模式:
- 浮点运算的所有输入在其表示的精度中都是非正规化的数字,它们被视为零,并且与输入具有相同的符号。
- 所有浮点异常的发生都是使用被此机制视为零的输入值确定的。
如果在指令的任何输出上使用清零模式:
- 如果指令指定的运算舍入前的结果满足条件,则输出返回为零,符号位与结果相同;
- 在许多算法上,它没有明显的效果,因为该算法通常不使用非规范化数字;
- 在其他算法上,可能会导致异常发生或严重降低算法结果的准确性。
2. Arm内存模式
Arm内存模型支持:
- 在未对齐的内存访问上生成异常;
- 限制应用程序对指定内存区域的访问;
- 将执行指令提供的虚拟地址(VAs)转换为物理地址(PA);
- 在大端和小端之间改变多字节数据的解释;
- 控制访问内存的顺序;
- 控制高速缓存和地址转换结构;
- 同步多个PE对共享内存的访问;
- 控制和防止推测性访问内存的障碍。
虚拟内存支持取决于执行状态:
AArch64状态: 支持64位虚拟寻址,转换控制寄存器确定支持的虚拟内存(VA)范围。EL0和EL1的执行支持两个独立的VA范围,每个范围都有自己的翻译控件;
AArch32状态: 支持32位虚拟寻址,转换控制寄存器确定支持的VA范围。为了在EL1和EL0上执行,系统软件可以将VA范围分成两个子范围,每个子范围都有自己的转换控件。
无论执行状态如何,虚拟内存系统架构(VMSA)都可将VAs转换为支持的PA空间内任何位置的内存块或内存页。