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 國際官方規範頁面,但它往往明顯落後於上面鏈接的規範。請務必查看尚未整合擴展的 Wiki,並請注意,除此之外,我們有時還支持尚未批准的擴展(這些將被標記為實驗性的 - 見下文)並支持各種供應商特定的擴展(見下文)。

目前已知的與規範的差異有

  • 無條件允許來自 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 將會啟用 zicond 附加元件,以及 rva20u64 設定檔中的附加元件。

除非指定 -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

組譯支援

Zvknhb

組譯支援

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 位元,因此僅在 VLEN>=64 時才支援 Zve32xZve32f。組合語言支援沒有此限制。

Zicntr, Zicsr, Zifencei, Zihpm

在基本 I 規範的 2.0 和 2.1 版之間,進行了向後不相容的變更,從基本 ISA 中移除選定的指令和 CSR。這些指令被分組到一組新的擴充套件中,但基本 ISA 不再需要它們。此變更在規範文件「文件版本 20190608-Base-Ratified 的前言」中有部分描述(未提及 zicntrzihpm 位元)。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。由於 ABI 相容性,編譯器不會在 RV32 上產生 amocas.d,也不會在 RV64 上產生 amocas.q。這些只能在組建器中使用。在 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 International 標準化的擴充功能。 廠商擴充功能一詞大致上與第一冊: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 版。所有指令都以 th. 作為前綴,如規範和上面連結的 riscv-toolchain-convention 文件中所述。

XVentanaCondOps

LLVM 實作了由 Ventana Micro Systems 制定的 VTx 系列自訂指令規範 1.0.0 版。所有指令都以 vt. 作為前綴,如規範和上面連結的 riscv-toolchain-convention 文件中所述。這些指令目前僅適用於 riscv64。

XSfvcp

LLVM 實作了由 SiFive 制定的 SiFive 向量協同處理器介面 (VCIX) 軟體規範 1.1.0 版。所有指令都以 sf.vc. 作為前綴,如規範和上面連結的 riscv-toolchain-convention 文件中所述。

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/南京沁恆微電子所設計的 某些 QingKe 核心中的自定義壓縮操作碼。供應商將這些操作碼稱為「XW」。

實驗性 C 內建函數

在某些情況下,擴展功能是非實驗性的,但該擴展功能的 C 內建函數仍然是實驗性的。若要從 clang 中使用此類擴展功能的 C 內建函數,您必須在命令列中加入 -menable-experimental-extensions。這目前適用於以下擴展功能

  • Zvbb

  • Zvbc

  • Zvkb

  • Zvkg

  • Zvkn

  • Zvknc

  • Zvkned

  • Zvkng

  • Zvknha

  • Zvknhb

  • Zvks

  • Zvksc

  • Zvksed

  • Zvksg

  • Zvksh

  • Zvkt