RISC-V 目标用户指南¶
简介¶
RISC-V 目标提供了针对实现 RISC-V 规范支持变体的处理器的代码生成。它位于 llvm/lib/Target/RISCV
目录中。
规范文档¶
RISC-V 规范已经过多次修订。LLVM 旨在实现标准 RISC-V 基础 ISA 和 ISA 扩展的最新批准版本,并具有务实的差异。最新的规范可以在以下位置找到: https://github.com/riscv/riscv-isa-manual/releases/.
官方 RISC-V 国际规范页面 也值得查看,但往往滞后于上面链接的规范。请务必查看 尚未集成的扩展的维基页面,并注意,此外,我们有时还会支持尚未批准的扩展(这些扩展将被标记为实验性 - 见下文)并支持各种特定于供应商的扩展(见下文)。
当前已知的规范偏差为
无条件允许来自 zifencei、zicsr、zicntr 和 zihpm 的指令,而无需根据启用的扩展来对其进行门控。以前版本的规范将这些指令包含在基础 ISA 中,我们保留此行为以避免破坏现有代码。如果规范的未来版本将这些操作码重新用于其他扩展,我们可能需要重新评估此选择,因此建议用户迁移构建系统,以免依赖于此。
允许命名 CSR 而无需根据特定扩展进行门控。这适用于所有 CSR 名称,而不仅仅是 zicsr、zicntr 和 zihpm 中的那些。
在用户指定的 ISA 命名字符串(例如
-march
)中未强制执行以z*
、s*
和x*
为前缀的扩展名称的顺序。
我们目前正在积极决定不在这时支持多个规范修订版。我们承认将来可能需要这样做,但会积极推迟围绕处理此问题的决策,直到我们有真实的硬件发货的具体示例以及随后对规范进行的不兼容更改。
基础 ISA¶
规范定义了五个基本指令集:RV32I、RV32E、RV64I、RV64E 和 RV128I。目前,LLVM 完全支持 RV32I 和 RV64I。RV32E 和 RV64E 仅由基于汇编的工具支持。RV128I 不受支持。
要指定目标三元组
¶ 架构
描述
riscv32
XLEN=32 的 RISC-V(即 RV32I 或 RV32E)
riscv64
XLEN=64 的 RISC-V(即 RV64I 或 RV64E)
要选择 E 变体 ISA(例如 RV32E 而不是 RV32I),请使用基础架构字符串(例如 riscv32
)和扩展 e
。
配置¶
可以使用 -march
传递支持的配置名称,而不是标准的 ISA 命名字符串。当前支持的配置
rvi20u32
rvi20u64
rva20u64
rva20s64
rva22u64
rva22s64
请注意,您还可以附加要启用的其他扩展名称,例如 rva20u64_zicond
将除了 rva20u64
配置中的扩展之外,还会启用 zicond
扩展。
除非指定了 -menable-experimental-extensions
(或其他工具的等效项),否则无法使用尚未批准的配置。这适用于以下配置
rva23u64
rva23s64
rvb23u64
rvb23s64
rvm23u32
扩展¶
下表提供了已批准且具有最终规范的扩展的状态摘要。在相关情况下,支持的详细说明将在后面给出。
¶ 扩展
状态
A
支持
B
支持
C
支持
D
支持
F
支持
E
支持(参见注释)
H
汇编支持
M
支持
Shcounterenw
汇编支持(参见注释)
Shgatpa
汇编支持(参见注释)
Shtvala
汇编支持(参见注释)
Shvsatpa
汇编支持(参见注释)
Shvstvala
汇编支持(参见注释)
Shvstvecd
汇编支持(参见注释)
Smaia
支持
Smcdeleg
支持
Smcsrind
支持
Smepmp
支持
Smstateen
汇编支持
Ssaia
支持
Ssccfg
支持
Ssccptr
汇编支持(参见注释)
Sscofpmf
汇编支持
Sscounterenw
汇编支持(参见注释)
Sscsrind
支持
Ssqosid
汇编支持
Ssstateen
汇编支持(参见注释)
Ssstrict
汇编支持(参见注释)
Sstc
汇编支持
Sstvala
汇编支持(参见注释)
Sstvecd
汇编支持(参见注释)
Ssu64xl
汇编支持(参见注释)
Svade
汇编支持(参见注释)
Svadu
汇编支持
Svbare
汇编支持(参见注释)
Svinval
汇编支持
Svnapot
汇编支持
Svpbmt
支持
V
支持
Za128rs
支持(参见注释)
Za64rs
支持(参见注释)
Zaamo
汇编支持
Zabha
支持
Zalrsc
汇编支持
Zama16b
支持(参见注释)
Zawrs
汇编支持
Zba
支持
Zbb
支持
Zbc
支持
Zbkb
支持(参见注释)
Zbkc
支持
Zbkx
支持(参见注释)
Zbs
支持
Zca
支持
Zcb
支持
Zcd
支持
Zcf
支持
Zcmop
支持
Zcmp
支持
Zcmt
汇编支持
Zdinx
支持
Zfa
支持
Zfbfmin
支持
Zfh
支持
Zfhmin
支持
Zfinx
支持
Zhinx
支持
Zhinxmin
支持
Zic64b
支持(参见注释)
Zicbom
汇编支持
Zicbop
支持
Zicboz
汇编支持
Ziccamoa
支持(参见注释)
Ziccif
支持(参见注释)
Zicclsm
支持(参见注释)
Ziccrse
支持(参见注释)
Zicntr
(参见注释)
Zicond
支持
Zicsr
(参见注释)
Zifencei
(参见注释)
Zihintntl
支持
Zihintpause
汇编支持
Zihpm
(参见注释)
Zimop
支持
Zkn
支持
Zknd
支持(参见注释)
Zkne
支持(参见注释)
Zknh
支持(参见注释)
Zksed
支持(参见注释)
Zksh
支持(参见注释)
Zk
支持
Zkr
支持
Zks
支持
Zkt
支持
Zmmul
支持
Ztso
支持
Zvbb
汇编支持
Zvbc
汇编支持
Zve32x
(部分)支持
Zve32f
(部分)支持
Zve64x
支持
Zve64f
支持
Zve64d
支持
Zvfbfmin
支持
Zvfbfwma
支持
Zvfh
支持
Zvkb
汇编支持
Zvkg
汇编支持
Zvkn
汇编支持
Zvknc
汇编支持
Zvkned
汇编支持
Zvkng
汇编支持
Zvknha
汇编支持
Zvknha
汇编支持
Zvks
汇编支持
Zvksc
汇编支持
Zvksed
汇编支持
Zvksg
汇编支持
Zvksh
汇编支持
Zvkt
汇编支持
Zvl32b
(部分)支持
Zvl64b
支持
Zvl128b
支持
Zvl256b
支持
Zvl512b
支持
Zvl1024b
支持
Zvl2048b
支持
Zvl4096b
支持
Zvl8192b
支持
Zvl16384b
支持
Zvl32768b
支持
Zvl65536b
支持
- 汇编支持
LLVM 支持汇编中相关的指令。所有与汇编相关的工具(例如汇编器、反汇编器、llvm-objdump 等)都受支持。编译器和链接器将接受扩展名称,并且链接的二进制文件将包含适当的 ELF 标志和属性以反映命名扩展的使用。
- 支持
完全受编译器支持。这包括汇编支持中的所有内容,以及 - 如果相关 - 指令的 C 语言内联函数以及编译器识别可降低到相关指令的惯用模式的模式匹配。
E
RV32E/RV64E 和 ilp32e/lp64e ABI 的支持处于实验阶段。为了与 GCC 中 ilp32e 的实现兼容,我们不使用对齐寄存器来传递可变参数。此外,对于长度为 2*XLEN 的类型,我们将堆栈对齐设置为 4 字节。
Zbkb
、Zbkx
这些指令的模式匹配支持不完整。
Zknd
、Zkne
、Zknh
、Zksed
、Zksh
不存在模式匹配。因此,这些指令只能从汇编程序或通过内联函数调用来使用。
Zve32x
、Zve32f
、Zvl32b
LLVM 目前在编译期间假设最小 VLEN(向量寄存器宽度)为 64 位,因此
Zve32x
和Zve32f
仅在 VLEN>=64 时受支持。汇编支持没有此限制。
Zicntr
、Zicsr
、Zifencei
、Zihpm
在基础 I 规范的 2.0 版和 2.1 版之间,进行了一项向后不兼容的更改,以从基础 ISA 中删除选定的指令和 CSR。这些指令被分组到一组新的扩展中,但不再是基础 ISA 所必需的。此更改在规范文档(
zicntr
和zihpm
位未提及)中的“Document Version 20190608-Base-Ratified 前言”中进行了部分描述。LLVM 目前实现了基础规范的 2.1 版。为了保持兼容性,在-march
字符串中没有这些扩展的情况下,也会接受来自这些扩展的指令。LLVM 还允许在-march
字符串中显式指定扩展。
Za128rs
、Za64rs
、Zama16b
、Zic64b
、Ziccamoa
、Ziccif
、Zicclsm
、Ziccrse
、Shcounterenvw
、Shgatpa
、Shtvala
、Shvsatpa
、Shvstvala
、Shvstvecd
、Ssccptr
、Sscounterenw
、Ssstateen
、Ssstrict
、Sstvala
、Sstvecd
、Ssu64xl
、Svade
、Svbare
这些扩展定义为 RISC-V 配置文件规范 的一部分。它们本身没有引入任何新功能,而是描述了现有的硬件功能。
实验性扩展¶
LLVM 支持(在不同程度上)许多实验性扩展。所有实验性扩展都以 experimental-
作为前缀。工具链版本之间明确没有承诺兼容性,强烈建议普通用户不要在实验性扩展达到批准之前使用它们。
实验性支持的主要目标是通过提供实现的存在性证明,并简化针对大型代码库验证提议扩展价值的工作,来协助批准过程。预计实验性扩展将过渡到批准状态,或最终被删除。目前,是否接受实验性扩展的决定完全是根据具体情况做出的;如果您想提出建议,强烈建议参加双周一次的 RISC-V 同步电话会议。
experimental-ssnpm
、experimental-smnpm
、experimental-smmpm
、experimental-sspm
、experimental-supm
LLVM 实现 v1.0.0-rc2 规范。
experimental-zacas
LLVM 实现 1.0 版本规范。amocas.w 将用于 i32 cmpxchg。amocas.d 将用于 RV64 上的 i64 cmpxchg。编译器不会为 RV32 生成 amocas.d 或为 RV64 生成 amocas.q,因为 ABI 兼容性问题。这些只能在汇编器中使用。在 ABI 问题 解决之前,此扩展将保持为实验性。
experimental-zalasr
LLVM 实现 0.0.5 草案规范。
experimental-zicfilp
、experimental-zicfiss
LLVM 实现 1.0 版本规范。
experimental-zvbc32e
、experimental-zvkgs
LLVM 实现 0.7 版本规范。
experimental-smctr
、experimental-ssctr
LLVM 实现 1.0-rc3 规范。
要从 clang 中使用实验性扩展,必须将 -menable-experimental-extensions 添加到命令行中,并指定正在使用的实验性扩展的确切版本。要使用 LLVM 的内部开发工具(例如 llc、llvm-objdump、llvm-mc)中的实验性扩展,必须在扩展名称前加上 experimental-。请注意,您不需要在使用内部工具时指定版本,也不应该在使用 clang 时包含 experimental- 前缀。
供应商扩展¶
供应商扩展是指未由 RISC-V 国际标准化,而是由硬件供应商定义的扩展。供应商扩展一词大致与第一卷:RISC-V 无特权 ISA 规范第 1.3 节中“非标准”扩展的定义相平行。特别是,我们预计最终会接受“自定义”扩展和“不符合标准”扩展。
将根据具体情况考虑包含供应商扩展。所有提案都应提交到双周一次的 RISCV 同步电话会议进行讨论。有关可能考虑因素的一般性概述,请参阅 Clang 文档。
我们的目标是遵循 riscv-non-isa/riscv-toolchain-conventions 中描述的命名约定。对此命名的例外情况需要有充分的理由。
当前支持的供应商扩展有:
XTHeadBa
LLVM 实现阿里巴巴的 T-HEAD 指定的 THeadBa(地址生成)供应商定义指令。根据规范,指令以 th. 为前缀。
XTHeadBb
LLVM 实现阿里巴巴的 T-HEAD 指定的 THeadBb(基本位操作)供应商定义指令。根据规范,指令以 th. 为前缀。
XTHeadBs
LLVM 实现阿里巴巴的 T-HEAD 指定的 THeadBs(单比特操作)供应商定义指令。根据规范,指令以 th. 为前缀。
XTHeadCondMov
LLVM 实现阿里巴巴的 T-HEAD 指定的 THeadCondMov(条件移动)供应商定义指令。根据规范,指令以 th. 为前缀。
XTHeadCmo
LLVM 实现阿里巴巴的 T-HEAD 指定的 THeadCmo(缓存管理操作)供应商定义指令。根据规范,指令以 th. 为前缀。
XTHeadFMemIdx
LLVM 实现阿里巴巴的 T-HEAD 指定的 THeadFMemIdx(浮点数的索引内存操作)供应商定义指令。根据规范,指令以 th. 为前缀。
XTheadMac
LLVM 实现阿里巴巴的 T-HEAD 指定的 XTheadMac(乘加指令)供应商定义指令。根据规范,指令以 th. 为前缀。
XTHeadMemIdx
LLVM 实现阿里巴巴的 T-HEAD 指定的 THeadMemIdx(索引内存操作)供应商定义指令。根据规范,指令以 th. 为前缀。
XTHeadMemPair
LLVM 实现阿里巴巴的 T-HEAD 指定的 THeadMemPair(两个 GPR 内存操作)供应商定义指令。根据规范,指令以 th. 为前缀。
XTHeadSync
LLVM 实现阿里巴巴的 T-HEAD 指定的 THeadSync(多核同步指令)供应商定义指令。根据规范,指令以 th. 为前缀。
XTHeadVdot
LLVM 实现阿里巴巴的 T-HEAD 指定的 THeadV 系列自定义指令规范 1.0.0 版本。根据规范和上面链接的 riscv-toolchain-convention 文档,所有指令都以 th. 为前缀。
XVentanaCondOps
LLVM 实现 Ventana Micro Systems 指定的 VTx 系列自定义指令规范 1.0.0 版本。根据规范和上面链接的 riscv-toolchain-convention 文档,所有指令都以 vt. 为前缀。目前这些指令仅适用于 riscv64。
XSfvcp
LLVM 实现 SiFive 指定的 SiFive 向量协处理器接口 (VCIX) 软件规范 1.1.0 版本。根据规范和上面链接的 riscv-toolchain-convention 文档,所有指令都以 sf.vc. 为前缀。
XSfvqmaccdod
、XSfvqmaccqoq
LLVM 实现 SiFive 指定的 SiFive Int8 矩阵乘法扩展规范 1.1.0 版本。根据上面链接的规范,所有指令都以 sf. 为前缀。
Xsfvfnrclipxfqf
LLVM 实现 SiFive 指定的 FP32 到 Int8 范围裁剪指令扩展规范 1.0.0 版本。根据上面链接的规范,所有指令都以 sf. 为前缀。
Xsfvfwmaccqqq
LLVM 实现 SiFive 指定的 矩阵乘法累加指令扩展规范 1.0.0 版本。根据上面链接的规范,所有指令都以 sf. 为前缀。
XCVbitmanip
LLVM 实现 OpenHW Group 指定的 CORE-V 位操作自定义指令规范 1.0.0 版本。根据规范,所有指令都以 cv. 为前缀。
XCVelw
LLVM 实现 OpenHW Group 指定的 CORE-V 事件加载自定义指令规范 1.0.0 版本。根据规范,所有指令都以 cv. 为前缀。目前这些指令仅适用于 riscv32。
XCVmac
LLVM实现了OpenHW Group发布的CORE-V乘加(MAC)自定义指令规范1.0.0版本。所有指令都以cv.mac为前缀,如规范中所述。目前,这些指令仅适用于riscv32。
XCVmem
LLVM实现了OpenHW Group发布的CORE-V后增量加载和存储自定义指令规范1.0.0版本。所有指令都以cv.为前缀,如规范中所述。目前,这些指令仅适用于riscv32。
XCValu
LLVM实现了Core-V发布的Core-V ALU自定义指令规范1.0.0版本。所有指令都以cv.为前缀,如规范中所述。目前,这些指令仅适用于riscv32。
XCVsimd
LLVM实现了OpenHW Group发布的CORE-V SIMD自定义指令规范1.0.0版本。所有指令都以cv.为前缀,如规范中所述。
XCVbi
LLVM实现了OpenHW Group发布的CORE-V立即分支自定义指令规范1.0.0版本。所有指令都以cv.为前缀,如规范中所述。目前,这些指令仅适用于riscv32。
XSiFivecdiscarddlone
LLVM实现了SiFive发布的SiFive sf.cdiscard.d.l1指令。
XSiFivecflushdlone
LLVM实现了SiFive发布的SiFive sf.cflush.d.l1指令。
XSfcease
LLVM实现了SiFive发布的SiFive sf.cease指令。
Xwchc
LLVM实现了一些清科内核中存在的自定义压缩操作码,由WCH/南京沁恒微电子提供。供应商称这些操作码为“XW”。
实验性C内联函数¶
在某些情况下,扩展是非实验性的,但该扩展的C内联函数仍处于实验阶段。要从clang中使用此类扩展的C内联函数,必须在命令行中添加-menable-experimental-extensions。目前,这适用于以下扩展
Zvbb
Zvbc
Zvkb
Zvkg
Zvkn
Zvknc
Zvkned
Zvkng
Zvknha
Zvknha
Zvks
Zvksc
Zvksed
Zvksg
Zvksh
Zvkt