Skip to content
This repository has been archived by the owner on Apr 11, 2024. It is now read-only.

Update LoongArch psABI and toolchain conventions. #24

Merged
merged 1 commit into from
Nov 4, 2021

Conversation

scylaac
Copy link
Contributor

@scylaac scylaac commented Nov 1, 2021

No description provided.

@xen0n
Copy link
Contributor

xen0n commented Nov 2, 2021

cc @yetist @xry111

我家电脑炸了,晚上再细看,刚手机上简单刷了一遍,比先前的方案感觉顺滑多了,点赞!

@scylaac scylaac force-pushed the add-toolchain-conventions-update branch from 6970a09 to fe92224 Compare November 2, 2021 06:38
|描述

|-march=
|`native` `loongarch64` `la464`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

仍然不建议使用未分版本的 loongarch64 取值,原因见 #23 不再重复。

目前的取值可以在实现中予以保留,但不建议在各类文档中显著体现,为得是渐渐能将该用法退出使用。

Copy link
Contributor Author

@scylaac scylaac Nov 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个 loongarch64 包含的基础架构(也是它使能的全部指令集模块)就是 la64v100,确定不包括未来的版本更新。它假设的目标是一个指令集最小的LA64处理器,兼容性最强。

(文档里的 la64v100 实际上是一个内部抽象名称,不是命令行选项参数。)

-march 的含义是一组 ISA 模块构成的指令集范围,但不是什么组合都常用。如果指令集有更新,至少会对应一款新处理器。所以用实际的处理器核名称作为参数比较合适。这样 -mtune 的大部分取值也就不用分开枚举了,可以减少记忆负担。(版本多了可能会晕)

配置目标 ISA 时,首先从 -march 选项给出的指令集模块出发,然后叠加其他 ISA 相关选项的效应,得到编译器最终使用的指令集。如果有声明特定指令集特定版本的需求,可以考虑在后面这一种"递增配置选项"里面体现(比如可以叫 "-mver" "-msxver" 一类的名字)。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不同意向用户隐藏这些有用的细节,另外 loongarch64 表示 baseline (基线 = 所有龙芯平台功能的最大公约数)也值得商榷:从自然语言的角度,所有具体的 LA64 实现都满足 LA64,那么此处只写 loongarch64 就不提供任何额外信息。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

但是 x86-64 也有 -march=x86-64 这种东西……

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

而且对于 32 位平台上的编译器,或者是配置 -mabi=ilp32* 的情况,-march=loongarch64 其实是提供额外信息的。

Comment on lines +170 to +175
|`lp64d` |lp64 |64 / 64
|`lp64f` |lp64 |64 / 32
|`lp64s` |lp64 |64 / (无)
|`ilp32d` |ilp32 |32 / 64
|`ilp32f` |ilp32 |32 / 32
|`ilp32s` |ilp32 |32 / (无)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“数据模型”一栏的大小写 fix 一下,用大写(“LP64”、“ILP32”)?

|`<fabi_suffix>` 字符串 |含义
|`f64` |基础 ABI 使用 64 位浮点寄存器传参 (`lp64d` `ilp32d`)
|`f32` |基础 ABI 使用 32 位浮点寄存器传参 (`lp64f` `ilp32f`)
|`sfp` |基础 ABI 不使用浮点寄存器传参 (`lp64s` `ilp32s`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sf 即可吧?加 p 只是为了凑齐三个字符吗?从文字叙述中看不出。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是的,主要是为了对称。


|`lp64d` / `default`
|GNU/Linux
|`loongarch64-linux-gnuf64`
Copy link
Contributor

@xen0n xen0n Nov 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

之前上游工作参考的取值应该都是 loongarch64-linux-gnu,需要做打包、上游生态工作的同学们来确认下,如果现在再改一次成这个样子,工作量有多大。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@xry111 xry111 Nov 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以额外规定没有 suffix 的时候默认为 f64 吗?这样现有的脚本之类还能继续用。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--target=loongarch64-linux-gnu 默认为 f64 完全没问题,这里约束的主要是 multiarch 发行版的库路径名称。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

嗷,那不会引入除了重新编译以外的其他问题 (反正 ld.so 改名已经得重新编译了 :)


|`_LOONGARCH_ARCH`
|`"loongarch64"` `"la464"`
|相当于 `--with-arch` / `-march` 指定的目标 CPU 名称
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这边明确一下,如果命令行给的值是语法糖或者兼容名字,此处的值是命令行的原值还是标准化后的值,会影响代码写作和前向兼容性的。

例如,如果我们将 -march=loongarch64 实现为严格等价于 -march=la64v100,那么:

  • 如果我们此处拿到的是原值,那么使用该值的程序库为了兼容下游用户多样的编译参数,将不得不自行进行一次标准化,或者冗余写 #if _LOONGARCH_ARCH == "loongarch64" || _LOONGARCH_ARCH == "la64v100" 这样的东西;
  • 如果我们此处拿到的是标准化后的值,且没有办法拿到原值,那么万一未来的编译器将用户现在使用的取值对应的标准值变化了(例如用户给定 -march=foo,几个版本后 -march=foo 变成了 -march=bar 的别名),将 break 用户代码。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可能这里没说清楚,这个"相当"的意思是"取原值,如果没有给命令行选项,就取编译器构建时配置的默认值",不会做标准化。不同的 -march 选项值含义应当不一样。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

据我所知 gcc 的命令行参数可以有各种各样的变换(形如 %{xxx} 的写法,具体有点忘了,我开发机仍然跪着),现在这里不区分处理前后的值的话,会约束以后的代码实现。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里表达的意思其实是,如果命令行给了,就按照原文转达(包括"native"),不会做额外处理。

Comment on lines -38 to 40
* LoongArch ELF ABI:该手册介绍了 LoongArch ELF ABI
* 龙芯架构 ELF psABI:该手册介绍了龙芯架构 ELF psABI
** link:LoongArch-ELF-ABI-CN.html[HTML 版本]。
** link:LoongArch-ELF-ABI-CN.pdf[PDF 版本]。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

要不要顺便把文件名改了?可以这个 PR 搞定之后再来一个提交重命名掉。

|$r4-$r5
|$v0-$v1
|`$r4` - `$r5`
|`$v0` - `$v1`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

出于各下游项目的现状和技术细节等原因,不是所有项目都容许实现这套 v0/v1 == a0/a1 的别名。fv0/fv1 同理。

考虑到:

  • 这种命名纯粹是为了“长得更像”MIPS,
  • 且当前已经上游的 binutils 并没有旧世界早期工具链的 MIPS 汇编兼容性,
  • 其他复用 a0/a1 做返回值寄存器的架构都没有这种别名安排,

不建议显著标明该特性。建议参考下我在 #8 的一种改法(当时应该只有英文版,领会精神)。重点:

  • 说明该套别名的保留是历史原因,不建议新代码使用;
  • 不强制要求处理 LoongArch 指令集的项目都必须实现该套别名。

|===

`char` 是有符号类型。
对于任何<<base-abi-type-marks, 基础 ABI 类型>>,`char` 默认是有符号类型。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

因为存在 -munsigned-char -msigned-char 这种编译器命令行选项,建议在此处加入提醒文字,防止开发者误以为可以假设 char 一定为有符号类型。

Comment on lines +226 to +239
|lp64d
|`0x3`
|使用 64 位通用寄存器,64位浮点寄存器和栈传参,
数据模型为 "lp64"(`long` 和指针类型宽度为64位,`int` 为32位)

|lp64f
|`0x2`
|使用 64 位通用寄存器,32位浮点寄存器和栈传参,
数据模型为 "lp64"(`long` 和指针类型宽度为64位,`int` 为32位)

|lp64s
|`0x1`
|使用 64 位通用寄存器和栈传参,
数据模型为 "lp64"(`long` 和指针类型宽度为64位,`int` 为32位)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这边可以按数值的顺序排列,现在这样眼睛完全花掉。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有个疑问,这里说的 ABI 跟 glibc 中这个文件对各架构定义的ABI有没有关系?如果有的话,是不是再研究一下:

https://github.com/loongson/glibc/blob/b0a5cedc5952889f82b3c610671f7f2edffa01f2/sysdeps/generic/ldconfig.h#L26-L48

|`v0`
|`0x0`
|支持具有栈操作语义的重定位类型
|`.0`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ld-xxx.so.0 没有先例,这个可能讨论下?别的我个人认为都很 OK 了。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个虽然没有先例,但是也没发现有什么实际的限制,我们讨论了一下认为还可以。好处是可以直接和e_flags里面那两位的取值对齐。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果按照 semver 的规范,.0 表示 ABI 不稳定。当然我们也可以不按这个规范来 (它不是强制规定)。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

关于版本的定义,可以参见这个文件及它的历史记录:

https://github.com/loongson/glibc/blob/b0a5cedc5952889f82b3c610671f7f2edffa01f2/shlib-versions

比如,当没有为架构特别定义ld.so及版本时,使用 ld.so.1 这个标准名称,就是说ld.so真没有从0开始的:

# We use the ELF ABI standard name for the default.
ld=ld.so.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

或许把 ld.so 版本号和 psABI 版本解耦比较好,比如如果我们在下一个 psABI 版本引入了新的 reloc type (#9,或者新的指令也可能需要新的 reloc type),那么其实完全没有必要改变 ld.so 的版本号,因为这完全不会影响 ld.so 的工作。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我以为动态链接不用这些 reloc 的,刚才看了一下还真用了,那没事了

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对的;印象中,至少 TLS 那一套在 LA 目前上游了的 binutils 实现里是 open code 了宏展开,宏的求值就是要链接器进行的。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TLS确实需要静态链接器和ld.so配合。不过说到底就是静态链接器在GOT表里开了两个槽罢了,R_LARCH_SOP向指令位域中补充和tls有关的数据结构在GOT表中的偏移量。装载时,ld.so通过R_LARCH_TLS_*重定位修正GOT表里的内容,这一点应该和其他体系结构实现一致。
在我的设想中,如果想把R_LARCH_SOP换成直接修正指令位域,不会影响现有的可执行程序和动态库。不知道除此之外,R_LARCH_SOP的哪部分和运行时有关?谢谢

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

写上面评论的时候我可能困了或者心不在焉,动态链接不会用到 R_LARCH_SOP_*。我说的情况是基于我观察到一些伪指令在实现上大量使用四则运算,印象中 TLS 相关也使用了;具体还要看下。写那段话的时候我开发机是坏的,没法看代码。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我来了一发 readelf -r /usr/lib/* | grep SOP 没发现结果。

@scylaac scylaac force-pushed the add-toolchain-conventions-update branch from fe92224 to 77026a9 Compare November 2, 2021 12:00
v1.00
:docinfodir: ../themes
:docinfo: shared
:doctype: book
Copy link
Collaborator

@FreeFlyingSheep FreeFlyingSheep Nov 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

因为后面直接引用了images文件夹中的图片,所以要添加:imagesdir: ../images设置图片根路径。

:docinfodir: ../themes
:docinfo: shared
:doctype: book
:toc: left
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上,请添加:imagesdir: ../images,你可以发现目前预览版里面图片是无法正常显示的,预览版见 https://loongson.github.io/LoongArch-Documentation-Preview/ ,你也可以直接点击下面 checks 里面的按
钮。
QQ20211102-211047

在确定目标 ISA 配置时,应以 *基础架构* 隐含的 ISA 模块为基础,
再根据选用 / 关闭 ISA 扩展的命令行选项进行调整,得出结果。

image::compiler-isa-config-model-CN.svg[]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

svg 图片有更多的属性可以控制,具体可以参考 https://docs.asciidoctor.org/asciidoc/latest/macros/image-svg/ ,当然现在这样默认的也行。

@chenhuacai
Copy link

看来大家都还挺喜欢对称美的,我也喜欢。所以我对LP64跟ILP32的非对称表示不满。当然雪瑞同志对LP32也有意见。那么干脆我们的ABI跟C语言数据类型解绑,把L也去掉,直接叫P32/P64如何?

@xen0n
Copy link
Contributor

xen0n commented Nov 3, 2021

看来大家都还挺喜欢对称美的,我也喜欢。所以我对LP64跟ILP32的非对称表示不满。当然雪瑞同志对LP32也有意见。那么干脆我们的ABI跟C语言数据类型解绑,把L也去掉,直接叫P32/P64如何?

不认同,所谓形式上的对称永远应当让步于实质的一致性与历史沿革。LP64 ILP32 是早已通行的说法,用户、开发者群体已经熟知。至于 f32 f64 sfp 中的 sfp 纯粹只为凑齐 3 个字符,而将 f 加多一个字母,这更难以理解。保持三个字符串长度一样,除了可能对一些人感官上有所满足,没有任何其他好处,用户还要记住“软浮点”的 f 要写 fp 跟硬浮点写 f 不一样。

@yetist
Copy link
Contributor

yetist commented Nov 3, 2021

看来大家都还挺喜欢对称美的,我也喜欢。所以我对LP64跟ILP32的非对称表示不满。当然雪瑞同志对LP32也有意见。那么干脆我们的ABI跟C语言数据类型解绑,把L也去掉,直接叫P32/P64如何?

__loongarch____loongarch64__ 这种才叫对称美吧。

@chenhuacai
Copy link

看来大家都还挺喜欢对称美的,我也喜欢。所以我对LP64跟ILP32的非对称表示不满。当然雪瑞同志对LP32也有意见。那么干脆我们的ABI跟C语言数据类型解绑,把L也去掉,直接叫P32/P64如何?

__loongarch____loongarch64__ 这种才叫对称美吧。

是的,是需要这样写。另外我依然认为ABI的名字并不必须要等同数据类型的名字,甚至不要任何字幕前缀,直接用32s/32f/32d/64s/64f/64d我都觉得可以,甚至更好。

@ChenghuaXu
Copy link
Contributor

谢谢,各位的意见建议。目前看起来定不下了的是-mabi=xxx,我先按现在的合入进去了,准备发gcc patch,有需求再改。

@ChenghuaXu ChenghuaXu merged commit 19e3e88 into loongson:main Nov 4, 2021
@xen0n
Copy link
Contributor

xen0n commented Nov 4, 2021

sfp 没人觉得要改??

@xen0n
Copy link
Contributor

xen0n commented Nov 4, 2021

其他有好几个建议也没有改动,并且没有说明原因,你们这样对外部贡献者十分不礼貌!

@xen0n
Copy link
Contributor

xen0n commented Nov 4, 2021

看到了 #25,这样是好的,收回前面的气话。一般来讲,在开放社区干活,所有发表意见的人都表达了同意,或者超时(1到2周)之后,这时候才意味着共识达成,才能合并。

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants