寄存器使用约定
+名称 | +别名 | +用途 | +在调用中是否保留 | +
---|---|---|---|
|
+
|
+常数 |
+(常数) |
+
|
+
|
+返回地址 |
+否 |
+
|
+
|
+线程指针 |
+(不可分配) |
+
|
+
|
+栈指针 |
+是 |
+
|
+
|
+传参寄存器、返回值寄存器 |
+否 |
+
|
+
|
+传参寄存器 |
+否 |
+
|
+
|
+临时寄存器 |
+否 |
+
|
++ | 保留 |
+(不可分配) |
+
|
+
|
+栈帧指针 / 静态寄存器 |
+是 |
+
|
+
|
+静态寄存器 |
+是 |
+
名称 | +别名 | +用途 | +在调用中是否保留 | +
---|---|---|---|
|
+
|
+传参寄存器、返回值寄存器 |
+否 |
+
|
+
|
+传参寄存器 |
+否 |
+
|
+
|
+临时寄存器 |
+否 |
+
|
+
|
+静态寄存器 |
+是 |
+
临时寄存器也被称为调用者保存寄存器。 +静态寄存器也被称为被调用者保存寄存器。
+返回值寄存器的别名写法
+在一些早期的 LoongArch 汇编代码中,您可能会见到形如 $v0
$v1
$fv0
$fv1
+的寄存器写法:这些名字分别等价于 $a0
$a1
$fa0
$fa1
。
+这些别名最初是仿照 MIPS 的分立传参、返回值寄存器写法而设计的。
+由于 LoongArch 实际并没有专门的返回值寄存器,这种写法反而会造成误解,
+因而不建议使用。
由于各下游项目的实现细节差异, +给一个寄存器赋予多个 ABI 名字并不一定是简单的事情。 +新写作的处理 LoongArch 汇编语言的程序不应当实现该套别名。 +可移植的 LoongArch 汇编代码不应当使用该套别名。
+
+ Note
+ |
+
+
+
+对于龙芯公司提供的工具链组件,迁移流程为: +
+
+设本规范生效时相应组件的当前版本为 N, +
+
+
+
+对于这些组件相应的上游项目,已进入上游的那部分如果存在对该用法的支持,则按上述流程进行,“版本 N”理解为第一次加入 LoongArch 支持的那个正式发布版本。 +对于暂未进入上游,且不与预期必须使用该用法的其他组件交互的组件,上游版本将自始不支持该用法。 + |
+
C 语言数据类型规格
+标量类型 | +大小(字节) | +对齐(字节) | +
---|---|---|
|
+1 |
+1 |
+
|
+1 |
+1 |
+
|
+2 |
+2 |
+
|
+4 |
+4 |
+
|
+8 |
+8 |
+
|
+8 |
+8 |
+
指针类型 |
+8 |
+8 |
+
|
+4 |
+4 |
+
|
+8 |
+8 |
+
|
+16 |
+16 |
+
标量类型 | +大小(字节) | +对齐(字节) | +
---|---|---|
|
+1 |
+1 |
+
|
+1 |
+1 |
+
|
+2 |
+2 |
+
|
+4 |
+4 |
+
|
+4 |
+4 |
+
|
+8 |
+8 |
+
指针类型 |
+4 |
+4 |
+
|
+4 |
+4 |
+
|
+8 |
+8 |
+
|
+16 |
+16 |
+
对于任何基础 ABI 类型,char
默认是有符号类型。
ELF 目标文件
+本节内容中关于 ELF 目标文件的通用格式定义 +均参考 最新版本的 SysV gABI。
+EI_CLASS: ELF 文件格式
+EI_CLASS | +枚举值 | +含义 | +
---|---|---|
|
+
|
+32 位 ELF 格式 (ELF32) |
+
|
+
|
+64 位 ELF 格式 (ELF64) |
+
e_machine: 体系结构 ID
+LoongArch (258)
e_flags: ABI 类型和版本 ID
+[31:8] 位 |
+[7:6] 位 |
+[5:3] 位 |
+[2:0] 位 |
+
---|---|---|---|
(保留) |
+ABI 版本 |
+ABI 扩展特性 |
+基础 ABI 修饰符 |
+
EI_CLASS
和 e_flags[7:0]
完整确定了 ELF 目标文件使用的 ABI 类型。
其中,基础 ABI 类型由 EI_CLASS
和 e_flags[2:0]
共同标记,
+前者唯一确定了 C 语言整数和指针类型的表示(数据模型)和传参方式,
+后者则在此基础上表示其他基础 ABI 性质,如浮点类型传参方式,称为 基础 ABI 修饰符。
因此,龙芯架构的 ELF64 / ELF32 目标文件分别仅用于编码 lp64*
/ ilp32*
ABI 的程序。
0x0
0x4
0x5
0x6
0x7
为 e_flags[2:0]
的保留值。
基础 ABI 名称 | +EI_CLASS | +基础 ABI 修饰符 (e_flags[2:0] ) |
+含义 | +
---|---|---|---|
|
+
|
+
|
+使用 64 位通用寄存器和栈传参,
+数据模型为 |
+
|
+
|
+
|
+使用 64 位通用寄存器,32 位浮点寄存器和栈传参,
+数据模型为 |
+
|
+
|
+
|
+使用 64 位通用寄存器,64 位浮点寄存器和栈传参,
+数据模型为 |
+
|
+
|
+
|
+使用 32 位通用寄存器和栈传参,
+数据模型为 |
+
|
+
|
+
|
+使用 32 位通用寄存器,32 位浮点寄存器和栈传参,
+数据模型为 |
+
|
+
|
+
|
+使用 32 位通用寄存器,64 位浮点寄存器和栈传参,
+数据模型为 |
+
e_flags[5:3]
标记了 ABI 扩展特性。
ABI 扩展特性名称 | +e_flags[5:3] | +含义 | +
---|---|---|
|
+
|
+默认,无扩展特性 |
+
+ |
|
+保留值 |
+
e_flags[7:6]
标记了 ELF 目标文件使用的 ABI 版本。
ABI 版本 | +枚举值 | +描述 | +
---|---|---|
|
+
|
+支持具有栈操作语义的重定位类型 |
+
|
+
|
+支持指令立即数域语义的重定位类型,可以不兼容v0单独实现。 |
+
+ |
|
+保留值 |
+
重定位类型
+枚举值 | +名称 | +描述 | +语义 | +
---|---|---|---|
0 |
+
|
++ | + |
1 |
+
|
+动态符号地址解析 |
+
|
+
2 |
+
|
+动态符号地址解析 |
+
|
+
3 |
+
|
+模块动态加载地址修正 |
+
|
+
4 |
+
|
+可执行映像数据动态填充 |
+
|
+
5 |
+
|
+PLT 跳转支持 |
+由具体实现定义 |
+
6 |
+
|
+TLS-GD 动态重定位支持 |
+
|
+
7 |
+
|
+TLS-GD 动态重定位支持 |
+
|
+
8 |
+
|
+TLS-GD 动态重定位支持 |
+
|
+
9 |
+
|
+TLS-GD 动态重定位支持 |
+
|
+
10 |
+
|
+TLS-IE 动态重定位支持 |
+
|
+
11 |
+
|
+TLS-IE 动态重定位支持 |
+
|
+
12 |
+
|
+本地间接跳转解析 |
+
|
+
… 动态链接器保留项 |
+|||
20 |
+
|
+标记 la.abs 宏指令 |
+静态填充符号绝对地址 |
+
21 |
+
|
+标记外部标签跳转 |
+静态填充符号地址偏移量 |
+
22 |
+
|
+将符号相对地址压栈 |
+
|
+
23 |
+
|
+将常数或绝对地址压栈 |
+
|
+
24 |
+
|
+复制栈顶元素 |
+
|
+
25 |
+
|
+将符号的 GOT 表项偏移量压栈 |
+
|
+
26 |
+
|
+将 TLS-LE 偏移量压栈 |
+
|
+
27 |
+
|
+将 TLS-IE 偏移量压栈 |
+
|
+
28 |
+
|
+将 TLS-GD 偏移量压栈 |
+
|
+
29 |
+
|
+将符号 PLT stub 的地址偏移量压栈 |
+
|
+
30 |
+
|
+断言栈顶元素为真 |
+
|
+
31 |
+
|
+栈顶运算 |
+
|
+
32 |
+
|
+栈顶运算 |
+
|
+
33 |
+
|
+栈顶运算 |
+
|
+
34 |
+
|
+栈顶运算 |
+
|
+
35 |
+
|
+栈顶运算 |
+
|
+
36 |
+
|
+栈顶运算 |
+
|
+
37 |
+
|
+栈顶运算 |
+
|
+
38 |
+
|
+指令立即数重定位 |
+
带 5 位有符号数溢出检测功能 |
+
39 |
+
|
+指令立即数重定位 |
+
带 12 位无符号数溢出检测功能 |
+
40 |
+
|
+指令立即数重定位 |
+
带 12 位有符号数溢出检测功能 |
+
41 |
+
|
+指令立即数重定位 |
+
带 16 位有符号数溢出检测功能 |
+
42 |
+
|
+指令立即数重定位 |
+
带 18 位有符号数溢出和4字节对齐检测功能 |
+
43 |
+
|
+指令立即数重定位 |
+
带 20 位有符号数溢出检测功能 |
+
44 |
+
|
+指令立即数重定位 |
+
带 23 位有符号数溢出和4字节对齐检测功能 |
+
45 |
+
|
+指令立即数重定位 |
+
带 28 位有符号数溢出和4字节对齐检测功能 |
+
46 |
+
|
+指令修正 |
+
带 32 位无符号数溢出检测功能 |
+
47 |
+
|
+8 位原地加法 |
+
|
+
48 |
+
|
+16 位原地加法 |
+
|
+
49 |
+
|
+24 位原地加法 |
+
|
+
50 |
+
|
+32 位原地加法 |
+
|
+
51 |
+
|
+64 位原地加法 |
+
|
+
52 |
+
|
+8 位原地减法 |
+
|
+
53 |
+
|
+16 位原地减法 |
+
|
+
54 |
+
|
+24 位原地减法 |
+
|
+
55 |
+
|
+32 位原地减法 |
+
|
+
56 |
+
|
+64 位原地减法 |
+
|
+
57 |
+
|
+GNU C++ vtable 支持 |
++ |
58 |
+
|
+GNU C++ vtable 支持 |
++ |
… 保留项 |
+|||
64 |
+
|
+18 位相对 PC 跳转 |
+
带 18 位有符号数溢出和4字节对齐检测功能 |
+
65 |
+
|
+23 位相对 PC 跳转 |
+
带 23 位有符号数溢出和4字节对齐检测功能 |
+
66 |
+
|
+28 位相对 PC 跳转 |
+
带 28 位有符号数溢出和4字节对齐检测功能 |
+
67 |
+
|
+32/64 位绝对地址的 [31 … 12] 位 |
+
|
+
68 |
+
|
+32/64 位绝对地址的 [11 … 0] 位 |
+
|
+
69 |
+
|
+64 位绝对地址 [51 … 32] 位 |
+
|
+
70 |
+
|
+64 位绝对地址 [63 … 52] 位 |
+
|
+
71 |
+
|
+相对 PC 偏移 32/64 位的 [31 … 12] 位 |
+
|
+
72 |
+
|
+32/64 位地址的 [11 … 0] 位 |
+
|
+
73 |
+
|
+相对 PC 偏移 64 位的 [51 … 32] 位 |
+
|
+
74 |
+
|
+相对 PC 偏移 64 位的 [63 … 52] 位 |
+
|
+
75 |
+
|
+GOT 表项相对 PC 偏移 32/64 位的 [31 … 12] 位 |
+
|
+
76 |
+
|
+GOT 表项 32/64 位地址的 [11 … 0] 位 |
+
|
+
77 |
+
|
+GOT 表项相对 PC 偏移 64 位的 [51 … 32] 位 |
+
|
+
78 |
+
|
+GOT 表项相对 PC 偏移 64 位的 [63 … 52] 位 |
+
|
+
79 |
+
|
+GOT 表项 32/64 位绝对地址的 [31 … 12] 位 |
+
|
+
80 |
+
|
+GOT 表项 32/64 位绝对地址的 [11 … 0] 位 |
+
|
+
81 |
+
|
+GOT 表项 64 位绝对地址的 [51 … 32] 位 |
+
|
+
82 |
+
|
+GOT 表项 64 位绝对地址的 [63 … 52] 位 |
+
|
+
83 |
+
|
+TLS LE 符号相对 TP 寄存器偏移 32/64 位的 [31 … 12] 位 |
+
|
+
84 |
+
|
+TLS LE 符号相对 TP 寄存器偏移 32/64 位的 [11 … 0] 位 |
+
|
+
85 |
+
|
+TLS LE 符号相对 TP 寄存器偏移 64 位的 [51 … 32] 位 |
+
|
+
86 |
+
|
+TLS LE 符号相对 TP 寄存器偏移 64 位的 [63 … 52] 位 |
+
|
+
87 |
+
|
+TLS IE 符号 GOT 表项相对 PC 偏移 32/64 位的 [31 … 12] 位 |
+
|
+
88 |
+
|
+TLS IE 符号 GOT 表项 32/64 位地址的 [11 … 0] 位 |
+
|
+
89 |
+
|
+TLS IE 符号 GOT 表项相对 PC 偏移 64 位的 [51 … 32] 位 |
+
|
+
90 |
+
|
+TLS IE 符号 GOT 表项相对 PC 偏移 64 位的 [63 … 52] 位 |
+
|
+
91 |
+
|
+TLS IE 符号 GOT 表项 32/64 位绝对地址的 [31 … 12] 位 |
+
|
+
92 |
+
|
+TLS IE 符号 GOT 表项 32/64 位绝对地址的 [11 … 0] 位 |
+
|
+
93 |
+
|
+TLS IE 符号 GOT 表项 64 位绝对地址的 [51 … 32] 位 |
+
|
+
94 |
+
|
+TLS IE 符号 GOT 表项 64 位绝对地址的 [63 … 52] 位 |
+
|
+
95 |
+
|
+TLS LD 符号 GOT 表项相对 PC 偏移 32/64 位的 [31 … 12] 位 |
+
|
+
96 |
+
|
+TLS LD 符号 GOT 表项 32/64 位绝对地址的 [31 … 12] 位 |
+
|
+
97 |
+
|
+TLS GD 符号 GOT 表项相对 PC 偏移 32/64 位的 [31 … 12] 位 |
+
|
+
98 |
+
|
+TLS GD 符号 GOT 表项 32/64 位绝对地址的 [31 … 12] 位 |
+
|
+
99 |
+
|
+32 位相对 PC 偏移 |
+
|
+
100 |
+
|
+在相同的地址和其它重定位成对使用,标识指令可能被修改或删除(relaxed)。 |
++ |
动态链接器路径
+基础 ABI 类型 | +ABI 扩展特性 | +操作系统 / C 库 | +ELF interpreter 路径 | +
---|---|---|---|
|
+
|
+Linux, Glibc |
+
|
+
|
+
|
+Linux, Glibc |
+
|
+
|
+
|
+Linux, Glibc |
+
|
+
|
+
|
+Linux, Glibc |
+
|
+
|
+
|
+Linux, Glibc |
+
|
+
|
+
|
+Linux, Glibc |
+
|
+
附录:版本修订历史
+-
+
-
+
v1.00
+++-
+
-
+
新增寄存器使用惯例、数据类型惯例和重定位类型列表;
+
+
+ -
+
-
+
v2.00
+++-
+
-
+
新增 ILP32 数据模型说明;
+
+ -
+
新增返回值寄存器别名写法说明;
+
+ -
+
新增指令立即数域语义的重定位类型;
+
+ -
+
新增 ABI 规范修订时,工具链实现的指导迁移流程;
+
+ -
+
增加 SysV gABI 参考链接;
+
+ -
+
调整 asciidoc 代码风格;
+
+
+ -
+
-
+
v2.01
+++-
+
-
+
调整关于 ABI 类型在 ELF 文件中编码方式的说明;
+
+ -
+
各表格统一添加表头;
+
+
+ -
+