X86RegisterInfo.td 文件定义了 X86 架构的寄存器文件,包括:
- 寄存器本身的定义
- 寄存器之间的别名关系
- 由寄存器构建的寄存器类
主要组成部分
X86Reg 类定义
class X86Reg<string n, bits<16> Enc, list<Register> subregs = []> : Register<n> {
let Namespace = "X86";
let HWEncoding = Enc;
let SubRegs = subregs;
}
这是 X86 寄存器的基础类,继承自 LLVM 的 Register 类。它定义了:
- n: 寄存器名称
- Enc: 硬件编码
- subregs: 子寄存器列表
子寄存器索引定义
let Namespace = "X86" in {
def sub_8bit : SubRegIndex<8>;
def sub_8bit_hi : SubRegIndex<8, 8>;
// ... 其他子寄存器索引
}
这些定义用于标识寄存器的子部分,例如 8 位、16 位、32 位等子寄存器。
寄存器定义
文件中定义了多种类型的寄存器:
通用寄存器:
- 8 位寄存器:AL, CL, DL, BL, AH, CH, DH, BH 等
- 16 位寄存器:AX, CX, DX, SI, DI, BX, BP, SP 等
- 32 位寄存器:EAX, ECX, EDX, EBX, ESI, EDI, EBP, ESP 等
- 64 位寄存器:RAX, RCX, RDX, RBX, RSI, RDI, RBP, RSP 等
SIMD 寄存器:
- MMX 寄存器:MM0-MM7
- XMM 寄存器:XMM0-XMM31(用于 SSE)
- YMM 寄存器:YMM0-YMM31(用于 AVX)
- ZMM 寄存器:ZMM0-ZMM31(用于 AVX-512)
特殊寄存器:
- 段寄存器:CS, DS, SS, ES, FS, GS
- 调试寄存器:DR0-DR15
- 控制寄存器:CR0-CR15
- 标志寄存器:EFLAGS, DF
- 浮点控制寄存器:FPSW, FPCW, MXCSR
AVX-512 特定寄存器:
- 掩码寄存器:K0-K7
- Tile 寄存器:TMM0-TMM7
寄存器类定义
文件后半部分定义了各种寄存器类(RegisterClass),这些类将寄存器分组,用于指令选择和寄存器分配。例如:
def GR8 : RegisterClass<"X86", [i8], 8,
(add AL, CL, DL, AH, CH, DH, BL, BH, SIL, DIL, BPL, SPL,
R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B)> {
let AltOrders = [(sub GR8, AH, BH, CH, DH)];
let AltOrderSelect = [{
return MF.getSubtarget<X86Subtarget>().is64Bit();
}];
}
这个定义创建了一个名为 GR8 的寄存器类,包含所有 8 位通用寄存器,并定义了在不同模式下的分配顺序。
作用和重要性
- 寄存器描述:为 X86 架构的所有寄存器提供了完整的描述,包括名称、编码、大小和层次关系。
- 子寄存器关系:定义了寄存器之间的包含关系,例如 RAX 包含 EAX,EAX 包含 AX,AX 包含 AL 和 AH。
- 寄存器类:将寄存器分组为类,这些类用于:
- 指令选择:确定哪些寄存器可以用于特定指令
- 寄存器分配:指导编译器如何分配寄存器
- 约束处理:处理内联汇编中的寄存器约束
- 调试信息:通过 DwarfRegNum 提供了 DWARF 调试信息中的寄存器编号。
- 特殊属性:通过 CostPerUse、isAllocatable 等属性指定寄存器的使用成本和是否可分配,这些信息影响寄存器分配器的决策。
总结
X86RegisterInfo.td 是 LLVM X86 后端的核心文件之一,它定义了 X86 架构的寄存器模型。这些定义被 TableGen 工具处理,生成 C++ 代码,用于 LLVM 的代码生成阶段。通过这个文件,LLVM 能够理解 X86 寄存器的结构、关系和特性,从而进行有效的指令选择、寄存器分配和代码优化。
反映了 X86 架构的复杂性,包括从 16 位到 64 位的演进,以及各种扩展(如 MMX、SSE、AVX、AVX-512)添加的新寄存器。通过精确的寄存器描述,LLVM 能够为 X86 架构生成高效的机器代码。