周文嘉,目前就职于某国产 AI GPU 芯片公司,曾服务于 ARM、阿里巴巴、HTC 等公司,拥有 10 年以上工作经验,主要从事系统软件开发,涵盖系统库开发、指令集优化、Linux内核开发等,为某些开源社贡献过一定数量的补丁,担任 Free time team 创始人,致力于免费教育事业。
邵靖杰,目前就职于某国产大型机 ARM CPU 研究所,主要从事众核处理器的系统级缓存研发工作。
张健,先后在 SUSE、华为、区块链创业公司、寒武纪等公司工作,担任工程师、架构师、技术合伙人等,研究方向包括 ARM、Linux 发行版、Linux 内核、RISC-V 和虚拟化。
……
目录
作为 RISC 架构,AArch64 提供了大量的通用寄存器。除通用寄存器之外,本节还会介绍特殊寄存器、系统控制寄存器、处理器状态、函数调用标准。
1.2.1 通用寄存器
通用寄存器分为两类。其中一类寄存器包括 X0~X30,用于普通的指令集,每个寄存器都有 64 位(Xn)和 32 位(Wn)两种表示形式。其中 32 位的表示形式是 64 位表示形式的低 32位。另一类寄存器包括 V0~V31,用于浮点运算、SIMD、crypto 等领域。每个寄存器长度都是128 位(Qn),它们有 64 位(Dn)、32 位(Sn)、16 位(Hn)、8 位(Bn)这 4 种表示形式。以 X0 和 V0 为例,X0 是 64 位寄存器,它的低 32 位是 W0。V0 也称为 Q0,Q0 是一个128 位的寄存器,它的低 64 位称为 D0,它的低 32 位称为 S0,它的低 16 位称为 H0,它的低8 位称为 B0,如图 1.1 所示。
1.2.2 特殊寄存器
XZR 和 WZR 分别对应 64 位与 32 位的零寄存器。对这些寄存器进行读操作,将会获取到0;对这些寄存器进行的写操作将会被处理器忽略。与 ARM 的 32 位架构不同,PC 寄存器已经不再是一个通用寄存器,无法直接访问。ARM 指令的长度是 4 字节,因此对于 ARMv8 上的纯 ARM 指令来说,PC 寄存器是按字节对齐的。SP 寄存器也不再是一个通用寄存器,SP寄存器强制按 16 字节对齐。
1.2.3 系统控制寄存器
ARM 的系统控制寄存器都以“_ELx”为后缀,其中“x”表示某异常级别(Exception Level,EL)的一个数字,如 SCTLR_EL1。后缀的数字意味着能够访问该寄存器的最低异常级别,ARM的系统控制寄存器如表 1.1 所示。
MRS 和 MSR 指令用于读写系统控制寄存器,示例代码如下。
MRS X0, SCTLR_EL1 // X0 = SCTLR_EL1
MSR SCTLR_EL1, X0 // SCTLR_EL1 = X0
常用的系统控制寄存器及其功能如表 1.2 所示。
ARM 的系统控制寄存器数量庞大,详细的介绍可以参考文档 DDI0487F_b_ARMv8_arm.pdf。
1.2.4 处理器状态
AArch64 通过 PSTATE(process state)的标志位来保存处理器的状态,处理器执行指令的时候,可以读取和设置这些标志位。这些标志位既可以通过 mrs/msr 指令进行访问,也可以通过 DAIFSet、DAIFClr、SPSel、PAN、UAO 等指令直接访问。PSTATE 寄存器的标志位如表 1.3 所示。
1.2.5 函数调用标准
1.AArch64 基本指令集函数调用规则
AArch64 提供了 31 个 64 位的通用寄存器 X0~X30,SP 寄存器已经变成了一个专用寄存器。这些寄存器的描述如表 1.4 所示。
值得注意的是,X16 和 X17 寄存器在动态链接的时候,可能会被某些链接器用于实现特殊功能。X18 寄存器在 Darwin 和 Windows 平台上会保留作为平台寄存器使用。在代码优化的时候,这 3 个寄存器要谨慎使用。
2.AArch64 NEON
指令集函数调用规则 AArch64 提供了 32 个 128 位的寄存器(V0~31),可以用来进行 SIMD 和浮点运算。其中,V0~V7 这 8 个寄存器用来传递参数和函数返回值,V8~V15 这 8 个寄存器需要由被调函数保存(只需要保存这些寄存器的低 64 位即可)。D8~D15 是 V8~V15 寄存器的低 64 位,因此通过如下的代码片段保存 D8~D15 的内容,就可以在函数中使用 V0~V31 这 32 个寄存器了。
stp d8, d9, [sp, -192]!
stp d10, d11, [sp, 16]
stp d12, d13, [sp, 32]
stp d14, d15, [sp, 48]
3.AArch64 SVE
指令集函数调用规则 如果平台支持 SVE 扩展,那么 AArch64 会提供 32 个可变长的向量寄存器 Z0~Z31。每个寄存器都可以用来进行 SIMD 和浮点运算,其中 Z0~Z7 用来传递参数和函数返回值。Z8~Z15 这 8 个寄存器需要由被调函数保存(只需要保存这些寄存器的低 64 位即可)。AArch64 还为 SVE 提供了 16 个断言寄存器 P0~P15,其中 P0~P3 这 4 个寄存器用来传递参数和函数返回值。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !