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 不受支持。

要指定目标三元组

表 110 RISC-V 架构

架构

描述

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

扩展

下表提供了已批准且具有最终规范的扩展的状态摘要。在相关情况下,支持的详细说明将在后面给出。

表 111 按状态划分的已批准扩展

扩展

状态

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 字节。

ZbkbZbkx

这些指令的模式匹配支持不完整。

ZkndZkneZknhZksedZksh

不存在模式匹配。因此,这些指令只能从汇编程序或通过内联函数调用来使用。

Zve32xZve32fZvl32b

LLVM 目前在编译期间假设最小 VLEN(向量寄存器宽度)为 64 位,因此 Zve32xZve32f 仅在 VLEN>=64 时受支持。汇编支持没有此限制。

ZicntrZicsrZifenceiZihpm

在基础 I 规范的 2.0 版和 2.1 版之间,进行了一项向后不兼容的更改,以从基础 ISA 中删除选定的指令和 CSR。这些指令被分组到一组新的扩展中,但不再是基础 ISA 所必需的。此更改在规范文档(zicntrzihpm 位未提及)中的“Document Version 20190608-Base-Ratified 前言”中进行了部分描述。LLVM 目前实现了基础规范的 2.1 版。为了保持兼容性,在 -march 字符串中没有这些扩展的情况下,也会接受来自这些扩展的指令。LLVM 还允许在 -march 字符串中显式指定扩展。

Za128rsZa64rsZama16bZic64bZiccamoaZiccifZicclsmZiccrseShcounterenvwShgatpaShtvalaShvsatpaShvstvalaShvstvecdSsccptrSscounterenwSsstateenSsstrictSstvalaSstvecdSsu64xlSvadeSvbare

这些扩展定义为 RISC-V 配置文件规范 的一部分。它们本身没有引入任何新功能,而是描述了现有的硬件功能。

实验性扩展

LLVM 支持(在不同程度上)许多实验性扩展。所有实验性扩展都以 experimental- 作为前缀。工具链版本之间明确没有承诺兼容性,强烈建议普通用户不要在实验性扩展达到批准之前使用它们。

实验性支持的主要目标是通过提供实现的存在性证明,并简化针对大型代码库验证提议扩展价值的工作,来协助批准过程。预计实验性扩展将过渡到批准状态,或最终被删除。目前,是否接受实验性扩展的决定完全是根据具体情况做出的;如果您想提出建议,强烈建议参加双周一次的 RISC-V 同步电话会议。

experimental-ssnpmexperimental-smnpmexperimental-smmpmexperimental-sspmexperimental-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-zicfilpexperimental-zicfiss

LLVM 实现 1.0 版本规范

experimental-zvbc32eexperimental-zvkgs

LLVM 实现 0.7 版本规范

experimental-smctrexperimental-ssctr

LLVM 实现 1.0-rc3 规范

要从 clang 中使用实验性扩展,必须将 -menable-experimental-extensions 添加到命令行中,并指定正在使用的实验性扩展的确切版本。要使用 LLVM 的内部开发工具(例如 llcllvm-objdumpllvm-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. 为前缀。

XSfvqmaccdodXSfvqmaccqoq

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