寄存器使用约定
名称 | 别名 | 用途 | 在调用中是否保留 |
---|---|---|---|
|
|
常数 |
(常数) |
|
|
返回地址 |
否 |
|
|
线程指针 |
(不可分配) |
|
|
栈指针 |
是 |
|
|
传参寄存器、返回值寄存器 |
否 |
|
|
传参寄存器 |
否 |
|
|
临时寄存器 |
否 |
|
保留 |
(不可分配) |
|
|
|
栈帧指针 / 静态寄存器 |
是 |
|
|
静态寄存器 |
是 |
名称 | 别名 | 用途 | 在调用中是否保留 |
---|---|---|---|
|
|
传参寄存器、返回值寄存器 |
否 |
|
|
传参寄存器 |
否 |
|
|
临时寄存器 |
否 |
|
|
静态寄存器 |
是 |
临时寄存器也被称为调用者保存寄存器。 静态寄存器也被称为被调用者保存寄存器。
返回值寄存器的别名写法
在一些早期的 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 文件中编码方式的说明;
-
各表格统一添加表头;
-