Support more RISC-V backend features on rustc compiler
This pull request adds the following RISC-V compiler features:
- V for vector extension
- Zfinx, Zdinx, Zhinx and Zhinxmin float in integer register extensions
- Zfh, Zfhmin 16-bit float pointer extensions
- Zbkb, Zkbc, Zbkc, Zk* cryptography extensions
It matches name in LLVM feature and is_riscv_feature_detected!. In this case we can use `#[target_feature]` on new RISC-V features. Ref: https://github.com/rust-lang/stdarch/pull/1263#pullrequestreview-
825891905
Use `rustc --print target-features` under any RISC-V target (or with `--target`) to check the features the rustc compiler support.
<details>
```
luojia@luojia-virtual-machine:~/IntrinRiscv/stdarch-riscv-crypto$ cargo rustc -- --print target-features
Compiling stdarch-riscv-crypto v0.1.0 (/home/luojia/IntrinRiscv/stdarch-riscv-crypto)
Features supported by rustc for this target:
m - 'M' (Integer Multiplication and Division).
a - 'A' (Atomic Instructions).
c - 'C' (Compressed Instructions).
f - 'F' (Single-Precision Floating-Point).
d - 'D' (Double-Precision Floating-Point).
e - Implements RV32E (provides 16 rather than 32 GPRs).
v - 'V' (Vector Extension for Application Processors).
zfinx - 'Zfinx' (Float in Integer).
zdinx - 'Zdinx' (Double in Integer).
zhinx - 'Zhinx' (Half Float in Integer).
zhinxmin - 'Zhinxmin' (Half Float in Integer Minimal).
zfh - 'Zfh' (Half-Precision Floating-Point).
zfhmin - 'Zfhmin' (Half-Precision Floating-Point Minimal).
zbkb - 'Zbkb' (Bitmanip instructions for Cryptography).
zbkc - 'Zbkc' (Carry-less multiply instructions for Cryptography).
zbkx - 'Zbkx' (Crossbar permutation instructions).
zknd - 'Zknd' (NIST Suite: AES Decryption).
zkne - 'Zkne' (NIST Suite: AES Encryption).
zknh - 'Zknh' (NIST Suite: Hash Function Instructions).
zksed - 'Zksed' (ShangMi Suite: SM4 Block Cipher Instructions).
zksh - 'Zksh' (ShangMi Suite: SM3 Hash Function Instructions).
zkr - 'Zkr' (Entropy Source Extension).
zkn - 'Zkn' (NIST Algorithm Suite).
zks - 'Zks' (ShangMi Algorithm Suite).
zk - 'Zk' (Standard scalar cryptography extension).
zkt - 'Zkt' (Data Independent Execution Latency).
crt-static - Enables C Run-time Libraries to be statically linked.
Code-generation features supported by LLVM for this target:
64bit - Implements RV64.
experimental-zbe - 'Zbe' (Extract-Deposit 'Zb' Instructions).
experimental-zbf - 'Zbf' (Bit-Field 'Zb' Instructions).
experimental-zbm - 'Zbm' (Matrix 'Zb' Instructions).
experimental-zbp - 'Zbp' (Permutation 'Zb' Instructions).
experimental-zbr - 'Zbr' (Polynomial Reduction 'Zb' Instructions).
experimental-zbt - 'Zbt' (Ternary 'Zb' Instructions).
no-rvc-hints - Disable RVC Hint Instructions..
relax - Enable Linker relaxation..
reserve-x1 - Reserve X1.
reserve-x10 - Reserve X10.
reserve-x11 - Reserve X11.
reserve-x12 - Reserve X12.
reserve-x13 - Reserve X13.
reserve-x14 - Reserve X14.
reserve-x15 - Reserve X15.
reserve-x16 - Reserve X16.
reserve-x17 - Reserve X17.
reserve-x18 - Reserve X18.
reserve-x19 - Reserve X19.
reserve-x2 - Reserve X2.
reserve-x20 - Reserve X20.
reserve-x21 - Reserve X21.
reserve-x22 - Reserve X22.
reserve-x23 - Reserve X23.
reserve-x24 - Reserve X24.
reserve-x25 - Reserve X25.
reserve-x26 - Reserve X26.
reserve-x27 - Reserve X27.
reserve-x28 - Reserve X28.
reserve-x29 - Reserve X29.
reserve-x3 - Reserve X3.
reserve-x30 - Reserve X30.
reserve-x31 - Reserve X31.
reserve-x4 - Reserve X4.
reserve-x5 - Reserve X5.
reserve-x6 - Reserve X6.
reserve-x7 - Reserve X7.
reserve-x8 - Reserve X8.
reserve-x9 - Reserve X9.
save-restore - Enable save/restore..
sifive7 - SiFive 7-Series processors.
zba - 'Zba' (Address Generation Instructions).
zbb - 'Zbb' (Basic Bit-Manipulation).
zbc - 'Zbc' (Carry-Less Multiplication).
zbs - 'Zbs' (Single-Bit Instructions).
zve32f - 'Zve32f' (Vector Extensions for Embedded Processors with maximal 32 EEW and F extension).
zve32x - 'Zve32x' (Vector Extensions for Embedded Processors with maximal 32 EEW).
zve64d - 'Zve64d' (Vector Extensions for Embedded Processors with maximal 64 EEW, F and D extension).
zve64f - 'Zve64f' (Vector Extensions for Embedded Processors with maximal 64 EEW and F extension).
zve64x - 'Zve64x' (Vector Extensions for Embedded Processors with maximal 64 EEW).
zvl1024b - 'Zvl' (Minimum Vector Length) 1024.
zvl128b - 'Zvl' (Minimum Vector Length) 128.
zvl16384b - 'Zvl' (Minimum Vector Length) 16384.
zvl2048b - 'Zvl' (Minimum Vector Length) 2048.
zvl256b - 'Zvl' (Minimum Vector Length) 256.
zvl32768b - 'Zvl' (Minimum Vector Length) 32768.
zvl32b - 'Zvl' (Minimum Vector Length) 32.
zvl4096b - 'Zvl' (Minimum Vector Length) 4096.
zvl512b - 'Zvl' (Minimum Vector Length) 512.
zvl64b - 'Zvl' (Minimum Vector Length) 64.
zvl8192b - 'Zvl' (Minimum Vector Length) 8192.
Use +feature to enable a feature, or -feature to disable it.
For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2
Code-generation features cannot be used in cfg or #[target_feature],
and may be renamed or removed in a future version of LLVM or rustc.
Finished dev [unoptimized + debuginfo] target(s) in 0.03s
```
</details>
Proof of concept:
<details>
```rust
#![feature(link_llvm_intrinsics)]
#![feature(target_feature_11)]
#![feature(riscv_target_feature)]
extern "C" {
#[link_name = "llvm.riscv.sm3p0"]
fn llvm_sm3p0(x: u32) -> u32;
#[link_name = "llvm.riscv.sm3p1"]
fn llvm_sm3p1(x: u32) -> u32;
}
#[target_feature(enable = "zksh")]
pub unsafe fn sm3p0(x: u32) -> u32 {
unsafe { llvm_sm3p0(x) }
}
extern "C" {
#[link_name = "llvm.riscv.vsetvli"]
fn llvm_vsetvli(avl: usize, sew: usize, lmul: usize) -> usize;
#[link_name = "llvm.riscv.vsetvlimax"]
fn llvm_vsetvlimax(sew: usize, lmul: usize) -> usize;
}
#[target_feature(enable = "v")]
pub unsafe fn vsetvli<const SEW: usize, const LMUL: usize>(avl: usize) -> usize {
unsafe { llvm_vsetvli(avl, SEW, LMUL) }
}
```
</details>
r? `@Amanieu`