Skip to main content

ab_riscv_primitives/instructions/v/
zvexx.rs

1//! ZveXx extension (Vector Extension for Embedded Processors, ELEN=64, integer-only)
2
3#[doc(hidden)]
4pub mod arith;
5#[doc(hidden)]
6pub mod carry;
7#[doc(hidden)]
8pub mod config;
9#[doc(hidden)]
10pub mod fixed_point;
11#[doc(hidden)]
12pub mod load;
13#[doc(hidden)]
14pub mod mask;
15#[doc(hidden)]
16pub mod muldiv;
17#[doc(hidden)]
18pub mod perm;
19#[doc(hidden)]
20pub mod reduction;
21#[doc(hidden)]
22pub mod store;
23#[doc(hidden)]
24pub mod widen_narrow;
25
26use crate::hart::{HartConfig, VectorHartConfig, VectorLengths};
27use crate::instructions::v::zvexx::arith::ZveXxArithInstruction;
28use crate::instructions::v::zvexx::carry::ZveXxCarryInstruction;
29use crate::instructions::v::zvexx::config::ZveXxConfigInstruction;
30use crate::instructions::v::zvexx::fixed_point::ZveXxFixedPointInstruction;
31use crate::instructions::v::zvexx::load::{LoadStoreNreg, Nf, SegVmNf, ZveXxLoadInstruction};
32use crate::instructions::v::zvexx::mask::ZveXxMaskInstruction;
33use crate::instructions::v::zvexx::muldiv::ZveXxMulDivInstruction;
34use crate::instructions::v::zvexx::perm::ZveXxPermInstruction;
35use crate::instructions::v::zvexx::reduction::ZveXxReductionInstruction;
36use crate::instructions::v::zvexx::store::ZveXxStoreInstruction;
37use crate::instructions::v::zvexx::widen_narrow::ZveXxWidenNarrowInstruction;
38use crate::instructions::v::{Eew, Elen, V, Vlen};
39use crate::instructions::zicsr::ZicsrInstruction;
40use crate::instructions::{ImplementedExtension, Instruction, IsaExtension};
41use crate::registers::general_purpose::Register;
42use crate::registers::vector::VReg;
43use ab_riscv_macros::instruction;
44use core::fmt;
45
46/// `zvl*b` extensions for each vector length
47const ZVL_EXTENSIONS: [(Vlen, &str); 12] = [
48    (Vlen::L32, "zvl32b"),
49    (Vlen::L64, "zvl64b"),
50    (Vlen::L128, "zvl128b"),
51    (Vlen::L256, "zvl256b"),
52    (Vlen::L512, "zvl512b"),
53    (Vlen::L1024, "zvl1024b"),
54    (Vlen::L2048, "zvl2048b"),
55    (Vlen::L4096, "zvl4096b"),
56    (Vlen::L8192, "zvl8192b"),
57    (Vlen::L16_384, "zvl16384b"),
58    (Vlen::L32_768, "zvl32768b"),
59    (Vlen::L65_536, "zvl65536b"),
60];
61
62/// ISA extensions of vector instructions for the vector lengths and the number of them.
63///
64/// Like compilers do, in addition to `zve32x` and `zve64x` (for `ELEN = 64`), this includes
65/// `zvl*b` extensions for all vector lengths up to `VLEN`.
66const fn vector_isa_extensions(
67    vector_lengths: VectorLengths,
68) -> ([IsaExtension; const { ZVL_EXTENSIONS.len() + 2 }], usize) {
69    // `zve32x` is always present, the rest of the array is overwritten below
70    let mut isa_extensions =
71        [IsaExtension::new("zve32x", 1, 0); const { ZVL_EXTENSIONS.len() + 2 }];
72    let mut num_isa_extensions = 1;
73    if matches!(vector_lengths.elen, Elen::L64) {
74        isa_extensions[num_isa_extensions] = IsaExtension::new("zve64x", 1, 0);
75        num_isa_extensions += 1;
76    }
77
78    // For loops are not yet usable in const environment
79    let mut index = 0;
80    while index < ZVL_EXTENSIONS.len() {
81        let (zvl_vlen, name) = ZVL_EXTENSIONS[index];
82        if zvl_vlen <= vector_lengths.vlen {
83            isa_extensions[num_isa_extensions] = IsaExtension::new(name, 1, 0);
84            num_isa_extensions += 1;
85        }
86        index += 1;
87    }
88
89    (isa_extensions, num_isa_extensions)
90}
91
92/// RISC-V ZveXx instruction.
93///
94/// `X` is any legal value, according to the RISC-V specification, for example, Zve32x or Zve64x.
95/// The actual `ELEN` and `VLEN` values are configured by the hart configuration, `ELEN` above 64
96/// is not supported and doesn't compile.
97#[instruction(
98    inherit = [
99        ZveXxConfigInstruction,
100        ZveXxLoadInstruction,
101        ZveXxStoreInstruction,
102        ZveXxArithInstruction,
103        ZveXxCarryInstruction,
104        ZveXxMulDivInstruction,
105        ZveXxWidenNarrowInstruction,
106        ZveXxFixedPointInstruction,
107        ZveXxMaskInstruction,
108        ZveXxReductionInstruction,
109        ZveXxPermInstruction,
110        ZicsrInstruction,
111    ],
112)]
113#[derive(Debug, Clone, Copy)]
114#[derive_const(PartialEq, Eq)]
115pub enum ZveXxInstruction<Hart>
116where
117    Hart: HartConfig, {}
118
119#[instruction]
120const impl<Reg, Hart> Instruction for ZveXxInstruction<Hart>
121where
122    Reg: [const] Register,
123    Hart: [const] VectorHartConfig<Reg = Reg>,
124{
125    const OWN_ISA_EXTENSIONS: &'static [IsaExtension] = {
126        assert!(
127            matches!(Hart::VECTOR_LENGTHS.elen, Elen::L32 | Elen::L64),
128            "Zve* extensions require `ELEN` of 32 or 64 bits"
129        );
130        let (isa_extensions, num_isa_extensions) =
131            &const { vector_isa_extensions(Hart::VECTOR_LENGTHS) };
132        isa_extensions.split_at(*num_isa_extensions).0
133    };
134
135    const ALIGNMENT: u8 = align_of::<u32>() as u8;
136
137    type Hart = Hart;
138
139    #[inline(always)]
140    #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
141    fn try_decode(instruction: u32) -> Option<Self> {
142        None
143    }
144
145    #[inline(always)]
146    fn size(&self) -> u8 {
147        size_of::<u32>() as u8
148    }
149}
150
151#[instruction]
152impl<Reg, Hart> fmt::Display for ZveXxInstruction<Hart>
153where
154    Reg: fmt::Display + Copy,
155    Hart: HartConfig<Reg = Reg>,
156{
157    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158        match self {}
159    }
160}