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

Add LoongArch toolchain conventions. #23

Closed
wants to merge 2 commits into from

Conversation

scylaac
Copy link
Contributor

@scylaac scylaac commented Oct 22, 2021

No description provided.

Comment on lines +28 to +34
|-march=
|`native` `loongarch64` `la464`
|选择目标 CPU (隐含默认 ABI 类型、ISA 扩展和调优参数)

|-mtune=
|`native` `loongarch64` `la464`
|选择目标 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 用于指定可用的最高指令集特性,-mtune 用于指定为哪个微架构进行指令调度。因此 -march 最好体现版本,-mtune 应当体现微架构型号。

la464 是修改译码器版 GS464V 的新名字,起个新名字我个人觉得没问题。但 loongarch64 我觉得比较有问题,因为不体现版本。如果不考虑 x32/n32 这类 ABI 的话,位数在 ABI 已经体现了,这里也没必要。我的建议是可以参考 HPPA 的做法,按照手册版本给此处意图所指的 generic LA 大版本起名;他们的做法是 -march=1.0 -march=1.1 -march=2.0。我们可以用 -march=1.00 表示支持 v1.00 手册中描述为必须实现的指令。

Comment on lines +36 to +42
|-mabi=
|`lp64` `ilp32`
|选择整型 ABI 类型

|-mfloat-abi=
|`double` `single` `soft`
|选择浮点 / 扩展 ABI 类型
Copy link
Contributor

Choose a reason for hiding this comment

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

-mfloat-abi 有个别架构是这么搞的,个人觉得也可以:

rg 'mfloat-abi' gcc/config/**/*.opt
gcc/config/nds32/nds32.opt
59:mfloat-abi=soft
63:mfloat-abi=hard

gcc/config/csky/csky.opt
60:Target RejectNegative Alias(mfloat-abi=, hard) Undocumented
63:Target RejectNegative Alias(mfloat-abi=, soft) Undocumented
65:mfloat-abi=v2
66:Target RejectNegative Alias(mfloat-abi=, hard) Undocumented
68:mfloat-abi=v1
69:Target RejectNegative Alias(mfloat-abi=, softfp) Undocumented
71:mfloat-abi=
77:Known floating-point ABIs (for use with the -mfloat-abi= option):

gcc/config/arm/arm.opt
104:mfloat-abi=
114:Known floating-point ABIs (for use with the -mfloat-abi= option):
151:Target RejectNegative Alias(mfloat-abi=, hard) Undocumented
182:Target RejectNegative Alias(mfloat-abi=, soft) Undocumented

尽管如此,个人仍然强烈倾向于、建议采用 RV 的做法:浮点 ABI 体现在 ABI 命名中,不单加选项。这是由于,讲话过程中只需要传递一个信息元素,理解起来很方便,且不会有歧义、生造表达方式等语言学问题。

举例说明,RV LP64D 这个 ABI 只有唯一的表述方式,就是字面写法;如果分为“整数 LP64 浮点 double(双精度)”两部分描述,那在一般的汉语语流中,可能会出现多种说法,“LP64双精度”“双精度LP64”“double LP64”“LP64 double”“LP64 ABI……其中浮点ABI为单精度……,为双精度……”等等无数种组合方式。代码上也会千奇百怪,要么拆两套枚举、参数,但有些时候只有一个枚举,那就会出现 LP64D LP64_D LP64_DP LP64DF LP64_DOUBLE_FP blah blah 多种命名,无法统一。

Copy link
Contributor Author

Choose a reason for hiding this comment

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

举例说明,RV LP64D 这个 ABI 只有唯一的表述方式,就是字面写法;如果分为“整数 LP64 浮点 double(双精度)”两部分描述,那在一般的汉语语流中,可能会出现多种说法,“LP64双精度”“双精度LP64”“double LP64”“LP64 double”“LP64 ABI……其中浮点ABI为单精度……,为双精度……”等等无数种组合方式。代码上也会千奇百怪,要么拆两套枚举、参数,但有些时候只有一个枚举,那就会出现 LP64D LP64_D LP64_DP LP64DF LP64_DOUBLE_FP blah blah 多种命名,无法统一。

目前文档描述的 / gcc 实现的标准 ABI 名称是 lp64/double,"lp64" 本身并不对应完整的 ABI 类型,只对应整型的表示和传参方式。

同样,在目前的 gcc 实现上 "-mabi=lp64" 也不隐含 "-mfloat-abi=double":若不给出 "-mfloat-abi" 选项,则只有 "-mfpu" 和 "-march" 可能隐含它的取值,如果这两者也没有给出,就采用 configure 时从 triplet 或 --with-float 选项获取的默认浮点 ABI 类型。

Copy link
Contributor

@xen0n xen0n Oct 27, 2021

Choose a reason for hiding this comment

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

目前文档描述的 / gcc 实现的标准 ABI 名称是 lp64/double,"lp64" 本身并不对应完整的 ABI 类型,只对应整型的表示和传参方式。

  • 这应该是龙芯独创的表示方式,加重了一些记忆负担,且没有明确的原因说明为何不按现有几种常见做法搞。个人觉得能蹭到已有惯例的就尽量蹭会比较好。如果是出于一些别的原因而必须“独创”,请说明原因,这样会给人非常亲和的印象。
  • 这里的 ABI 学名不是合法的标识符,会给下游需要以全名称呼 ABI 的场合带来不必要的麻烦和不一致(这一点可以参考 LA 指令集手册上形如 1RI21 的指令格式名称给下游带来的麻烦——名字起了个寂寞,没有一个项目按那几个名字来,全部都是生造,包括我的 loongarch-opcodes 项目)。建议至少加入推荐使用的标识符形式。
  • (这是个小问题)soft/single/double 名字长短不一,6 个字母有点长了。可以稍微再短点,soft/sp/dp 就好。

Copy link
Contributor Author

Choose a reason for hiding this comment

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

了解,我们再讨论一下应该怎么做。

Comment on lines +67 to +81
.龙芯架构 `machine` 字符串列表:
[%header,cols="^1,^2"]
|===
|`machine` 字符串
|含义

|`loongarch64`
|默认使用 la64 指令集,双精度浮点单元,ABI 类型 `lp64/double`

|`loongarch64nf`
|默认使用 la64 指令集,无硬件浮点单元,ABI 类型 `lp64/soft`

|`loongarch64sf`
|默认使用 la64 指令集,单精度浮点单元,ABI 类型 `lp64/single`
|===
Copy link
Contributor

Choose a reason for hiding this comment

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

强烈不建议如此,建议采用符合一般熟悉 ARM、MIPS 开发人员习惯的 loongarch64-unknown-xxx-xxxABIxx 写法。对应我在 #20 提出的「后缀“S/F/(空缺)”分别代表“软浮点/单精度硬浮点/双精度硬浮点”」方案,可以如此操作:

Triple 对应 ABI
loongarch64-unknown-xxx-xxx LP64 默认
loongarch64-unknown-xxx-xxxabilp64s LP64S
loongarch64-unknown-xxx-xxxabilp64f LP64F

这样做的好处有:

  • 先前早已推上游的 config.guess config.sub 可以不用再次改动。这俩文件牵扯的上游项目太多太多。
  • 与 Debian multiarch 一些既有架构的做法、LLVM、Rust 对多 ABI 平台的命名习惯一致。
  • gnueabi gnuabihf gnuabisf 这些 ARM 世界常用的 env 字段取值、gnuabi64 gnuabin32 这些 MIPS 世界常见的 env 字段取值,格式类似,干净熟悉。
  • 取值中包含完整的 ABI 名称,方便程序处理。

如果出于某些原因,这个信息一定、必须、非得要体现在 machine 字段的话,请说明这些原因,读文档的人猜不到。这种情况下可以这么做:

Triple 对应 ABI
loongarch64-unknown-xxx-xxx LP64 默认
loongarch64s-unknown-xxx-xxx LP64S
loongarch64f-unknown-xxx-xxx LP64F

由于这么搞一遍又要大动干戈去改几十上百个上游项目 vendor 的 config.guess config.sub 文件,重申一遍,强烈不建议改 machine 字段取值

Copy link
Contributor Author

Choose a reason for hiding this comment

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

上游的 config.guess config.sub 目前看来确实需要改,因为不打算单独搞一个"x32" ABI。

这里 GNU triplet machine 字段希望反映的是处理器支持的最高指令集特性(参照 i[34567]86)。根据手册描述,是否实现单/双精度 FPU 和龙芯架构基础整数指令集 (la32 / la64) 无关 ,也就是说,在 la64 下,至少可能有三个级别的指令集特性(而不仅仅是 ABI 特性)。所以就选择在这里反映出来了。

从实现看,这个 triplet 基本上只是一个用于让 GNU 构建系统判断是否进行交叉编译的符号。对于 GCC 来说,目前它的效果除了设定编译器类型,命令默认前缀和”-dumpmachine"选项的返回值之外,主要就是隐含 --with-arch / --with-float / --with-abi 选项的默认值。用其中任何一种 machine 搭配恰当的 --with- 选项也可以随意选择编译器的默认指令集和 ABI,另外两种不用也无所谓。

目前我们对 GNU 工具链和发行版的设想是:

  1. 编译使用的指令集特性和 ABI 尽量独立。在保持 ABI 兼容的同时,允许例程内部实现使用更高级的指令集特性。
    但这只用于保障二进制库末端用户的兼容性需求,原则上不应该发行这样的二进制库。

  2. 二进制发行版中,库使用的最大指令集特性和 ABI 类型应当一一对应。
    所以这里规定了 GNU/Linux Multiarch Identifier 的 os 字段必须是 -linux-gnu,因为 ABI 已经隐含在 machine 字段中(也就是说,只给每种指令集特性分配一个 multiarch 路径)。而对于 GNU triplet,文档并没有规定 os 字段是什么。目前的 GCC 实现也不会根据 os 设定默认 ABI 选项,因为不希望编译器用户随意错开默认的 ABI 和 ISA。

  3. 在使用不同指令集特性的龙芯架构发行版之间不需要交叉编译应用程序,只需要给支持 multilib 的工具链传递恰当的编译选项即可。
    但如果有用户希望这么做,并且不想更改 vendor 字段的话,就可以改 machine 字段来产生交叉编译器。

感谢建议,如果有必要我会补充一下额外说明。

Copy link
Contributor

Choose a reason for hiding this comment

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

如果要“反映处理器支持的最高指令集特性”,那么应该学习 HPPA,取 loongarch64v1.00-unknown-linux-gnu 这样的名字。(HPPA 使用 hppa2.0-unknown-linux-gnu 这样的写法,其中 2.0+ 隐含使用 64 位)注意,这和体现 ABI 是相互正交的两个话题;仍然推荐 ABI 在 env 字段体现(-linux-gnuabiXX 这样)。

Copy link
Contributor

Choose a reason for hiding this comment

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

另外,“处理器支持的指令集特性”这一点上 amd64/arm64 都做得很好,都有很多新功能迭代,但他们不动 machine 字段,也是龙芯当前的现状;其实可能基于现状结合 amd64/arm64 的实践,才是成本最低效益最高的。loongarchx32 可以默默地去掉,但不用急着往下游推,让它自然被历史遗忘即可;loongarch32/loongarch64 我觉得目前来看不动它也不会有任何不良后果,不会影响当下的适配,不会阻挡未来的演进。

Copy link
Contributor

Choose a reason for hiding this comment

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

我比较偏向于 loongarch64-unknown-xxx-xxxabilp64s,不过这里的问题是它应该表示“兼容 LP64S ABI,但可以使用 64 位浮点指令的代码”还是“LP64S ABI 的,只使用 32 位浮点指令的代码”。

前者很可能违背人类的直觉,但后者又和 “machine 段决定使用的指令集特性” 矛盾……

Comment on lines +110 to +116
|`__loongarch_gpr`
|`64`
|通用寄存器位宽

|`__loongarch_fpr`
|`0` `32` `64`
|浮点寄存器位宽(无 fpu 则为 `0` )
Copy link
Contributor

Choose a reason for hiding this comment

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

建议改成手册提到的 GRLEN FPLEN 固定缩写(写作 __loongarch_grlen __loongarch_fplen),目前这俩名字留作兼容。

docs/LoongArch-toolchain-conventions-CN.adoc Outdated Show resolved Hide resolved
@xen0n
Copy link
Contributor

xen0n commented Oct 27, 2021

cc @xry111

@scylaac
Copy link
Contributor Author

scylaac commented Nov 1, 2021

已参考各位意见更新:#24

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.

4 participants