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 時才支援
Zve32x
和Zve32f
。組合語言支援沒有此限制。
Zicntr
,Zicsr
,Zifencei
,Zihpm
在基本 I 規範的 2.0 和 2.1 版之間,進行了向後不相容的變更,從基本 ISA 中移除選定的指令和 CSR。這些指令被分組到一組新的擴充套件中,但基本 ISA 不再需要它們。此變更在規範文件「文件版本 20190608-Base-Ratified 的前言」中有部分描述(未提及
zicntr
和zihpm
位元)。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。由於 ABI 相容性,編譯器不會在 RV32 上產生 amocas.d,也不會在 RV64 上產生 amocas.q。這些只能在組建器中使用。在 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 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