Skip to content

Commit

Permalink
Add misc macro for vector extensions.
Browse files Browse the repository at this point in the history
Introduce `__riscv_min_vlen`, `__riscv_max_eew` and `__riscv_max_eew_fp`
macro, for let programer easier to get vector related information, like:

- What's the minimal VLEN value is guaranteed current architecture
  extension?
- What's the maximal available EEW is guaranteed current
  architecture extension?
- What's the maximal available EEW for floating-point operation is
  guaranteed current architecture extension?

It's possible to get the information by testing serveral architecture extension
test macro, but the life can be simpler if toolchain can help, for
example, if you want to check the minimal VLEN value via those macro:

```c
 #if defined(__riscv_zvl512b)
   #define __riscv_min_vlen 512
 #elif defined(__riscv_zvl256b)
   #define __riscv_min_vlen 256
 #elif defined(__riscv_zvl128b) || defined(__riscv_v)
   #define __riscv_min_vlen 128
 #elif defined(__riscv_zvl64b) || defined(__riscv_zve64x) || \
       defined(__riscv_zve64f) || defined(__riscv_zve64d)
   #define __riscv_min_vlen 64
 #elif defined(__riscv_zvl32b) || defined(__riscv_zve32x) || \
       defined(__riscv_zve32f)
   #define __riscv_min_vlen 32
 #endif

```

And it's not scalable solution since in theory we can have up to zvl32768b.
  • Loading branch information
kito-cheng committed Aug 19, 2021
1 parent 47f8c0f commit 549e7e1
Showing 1 changed file with 66 additions and 1 deletion.
67 changes: 66 additions & 1 deletion riscv-c-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,72 @@ https://creativecommons.org/licenses/by/4.0/.
| __riscv | 1 | Always defined. |
| __riscv_xlen | <ul><li>32 for rv32</li><li>64 for rv64</li><li>128 for rv128</ul> | Always defined. |
| __riscv_flen | <ul><li>32 if the F extension is available **or**</li><li>64 if `D` extension available **or**</li><li>128 if `Q` extension available</li></ul> | `F` extension is available. |
| __riscv_32e | 1 | `E` extension is available. |
| __riscv_32e | 1 | `E` extension is available. |
| __riscv_v_min_vlen | <N> | `V` or `Zve*` extensions are available, more detailed description see [__riscv_v_min_vlen](#__riscv_v_min_vlen) |
| __riscv_v_max_eew | <N> | `V` or `Zve*` extensions are available, more detailed description see [__riscv_v_max_eew](#__riscv_v_max_eew) |
| __riscv_v_max_eew_fp | <N> | `V` or `Zve*` extensions are available, more detailed description see [__riscv_v_max_eew_fp](#__riscv_v_max_eew_fp) |


### __riscv_v_min_vlen

This macro present the minimal VLEN in bit, which is guaranteed by the
architecture extension, e.g. `V` extension requires that VLEN ≥ 128, `Zve32*`
extension requires VLEN ≥ 32 and `Zve64*` extension requires VLEN ≥ 32; also
RISC-V have additional `Zvl*b` extensions to guarantee the minimal VLEN, that
will effect the value of `__riscv_v_min_vlen` too.

So the value of `__riscv_v_min_vlen` is defined by following rules:

- 128 if `V` extension is available.
- 32 if `Zve32x` or `Zve32f` extension is available.
- 64 if `Zve64x`, `Zve64f` or `Zve64d` extension is available.
- `N` if `Zvl<N>b` extension is available, and if `N` is large than the value
defined above.
- `__riscv_v_min_vlen` is undefined if all of above rule are not match.

Example:

- `__riscv_v_min_vlen` is 128 for `rv64gcv`
- `__riscv_v_min_vlen` is 512 for `rv32gcv_zv512b`
- `__riscv_v_min_vlen` is 256 for `rv32gcv_zvl32b_zv256b`
- `__riscv_v_min_vlen` is 128 for `rv64gcv_zvl32b`

### __riscv_v_max_eew

This marco present the maximal EEW (effective element width) value for
non-floating-point operations, which is guaranteed by the architecture
extension, e.g. `V` and `Zve64*` extension require EEW of 8, 16, and 32, and 64,
but `Zve32*` only require EEW of 8, 16, and 32.

The value of `__riscv_v_max_eew`:

- `__riscv_v_max_eew` is 64 if `V`, `Zve64x`, `Zve64f` or `Zve64d` extension
is available.
- `__riscv_v_max_eew` is 32 if `Zve32x` or `Zve32f` extension is available.
- `__riscv_v_max_eew` is undefined if all of above rule are not match.

NOTE: Toolchain may support integer vector type large than `__riscv_v_max_eew`,
but it migth cause illegal instruction exception at run-time.

### __riscv_v_max_eew_fp

This marco present the maximal EEW value for floating-point operations,
which is guaranteed by the architecture extension, e.g. Support of
floating-point operands with EEW=32 or EEW=64 are required by `V` extension and
`zve64d` extension, `Zve32f` and `Zve64f` only require support
floating-point operations with EEW=32, and `Zve32x` and `Zve64x` are not supprot
floating-point operations.

The value of `__riscv_v_max_eew_fp`:

- `__riscv_v_max_eew_fp` is 64 if `V` or `Zve64d` extension is available.
- `__riscv_v_max_eew_fp` is 32 if `Zve64f` or `Zve32d` extension is available.
- `__riscv_v_max_eew_fp` is 0 if `Zve64x` or `Zve32x` extension is available.
- `__riscv_v_max_eew_fp` is undefined if all of above rule are not match.

NOTE: Toolchain may support floating-point vector type large than
`__riscv_v_max_eew_fp`, but it migth cause illegal instruction exception
at run-time.

### Architecture Extension Test Macro

Expand Down

0 comments on commit 549e7e1

Please sign in to comment.