Skip to main content

ab_riscv_primitives/registers/
vector.rs

1//! RISC-V vector registers
2
3use crate::instructions::v::VRegGroupSize;
4use core::fmt;
5
6/// RISC-V vector register (v0-v31)
7#[derive(Clone, Copy)]
8#[derive_const(PartialEq, Eq)]
9#[repr(u8)]
10pub enum VReg {
11    /// Vector register v0 (also used as mask register)
12    V0 = 0,
13    /// Vector register v1
14    V1 = 1,
15    /// Vector register v2
16    V2 = 2,
17    /// Vector register v3
18    V3 = 3,
19    /// Vector register v4
20    V4 = 4,
21    /// Vector register v5
22    V5 = 5,
23    /// Vector register v6
24    V6 = 6,
25    /// Vector register v7
26    V7 = 7,
27    /// Vector register v8
28    V8 = 8,
29    /// Vector register v9
30    V9 = 9,
31    /// Vector register v10
32    V10 = 10,
33    /// Vector register v11
34    V11 = 11,
35    /// Vector register v12
36    V12 = 12,
37    /// Vector register v13
38    V13 = 13,
39    /// Vector register v14
40    V14 = 14,
41    /// Vector register v15
42    V15 = 15,
43    /// Vector register v16
44    V16 = 16,
45    /// Vector register v17
46    V17 = 17,
47    /// Vector register v18
48    V18 = 18,
49    /// Vector register v19
50    V19 = 19,
51    /// Vector register v20
52    V20 = 20,
53    /// Vector register v21
54    V21 = 21,
55    /// Vector register v22
56    V22 = 22,
57    /// Vector register v23
58    V23 = 23,
59    /// Vector register v24
60    V24 = 24,
61    /// Vector register v25
62    V25 = 25,
63    /// Vector register v26
64    V26 = 26,
65    /// Vector register v27
66    V27 = 27,
67    /// Vector register v28
68    V28 = 28,
69    /// Vector register v29
70    V29 = 29,
71    /// Vector register v30
72    V30 = 30,
73    /// Vector register v31
74    V31 = 31,
75}
76
77impl VReg {
78    /// Create a vector register from its 5-bit encoding
79    #[inline(always)]
80    pub const fn from_bits(bits: u8) -> Option<Self> {
81        match bits {
82            0 => Some(Self::V0),
83            1 => Some(Self::V1),
84            2 => Some(Self::V2),
85            3 => Some(Self::V3),
86            4 => Some(Self::V4),
87            5 => Some(Self::V5),
88            6 => Some(Self::V6),
89            7 => Some(Self::V7),
90            8 => Some(Self::V8),
91            9 => Some(Self::V9),
92            10 => Some(Self::V10),
93            11 => Some(Self::V11),
94            12 => Some(Self::V12),
95            13 => Some(Self::V13),
96            14 => Some(Self::V14),
97            15 => Some(Self::V15),
98            16 => Some(Self::V16),
99            17 => Some(Self::V17),
100            18 => Some(Self::V18),
101            19 => Some(Self::V19),
102            20 => Some(Self::V20),
103            21 => Some(Self::V21),
104            22 => Some(Self::V22),
105            23 => Some(Self::V23),
106            24 => Some(Self::V24),
107            25 => Some(Self::V25),
108            26 => Some(Self::V26),
109            27 => Some(Self::V27),
110            28 => Some(Self::V28),
111            29 => Some(Self::V29),
112            30 => Some(Self::V30),
113            31 => Some(Self::V31),
114            _ => None,
115        }
116    }
117
118    /// Return the 5-bit encoding of this register
119    #[inline(always)]
120    pub const fn to_bits(self) -> u8 {
121        self as u8
122    }
123
124    /// Whether this register can be the base of a register group of `group` registers.
125    ///
126    /// The base of a register group must be a multiple of the group size.
127    #[inline(always)]
128    pub const fn is_group_aligned(self, group: VRegGroupSize) -> bool {
129        self.to_bits().is_multiple_of(group.get())
130    }
131}
132
133impl fmt::Display for VReg {
134    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135        write!(f, "v{}", *self as u8)
136    }
137}
138
139impl fmt::Debug for VReg {
140    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141        fmt::Display::fmt(self, f)
142    }
143}
144
145// TODO: CSR composition?
146/// Vector CSR addresses
147#[derive(Debug, Clone, Copy)]
148#[derive_const(PartialEq, Eq)]
149pub enum VectorCsr {
150    /// Vector start element index (URW)
151    Vstart,
152    /// Fixed-point saturation flag (URW)
153    Vxsat,
154    /// Fixed-point rounding mode (URW)
155    Vxrm,
156    /// Vector control and status register (URW)
157    Vcsr,
158    /// Vector length (URO)
159    Vl,
160    /// Vector data type register (URO)
161    Vtype,
162    /// VLEN/8 (vector register length in bytes) (URO)
163    Vlenb,
164}
165
166impl VectorCsr {
167    /// Try to match a CSR index to a vector CSR
168    #[inline(always)]
169    pub const fn from_csr_index(index: u16) -> Option<Self> {
170        match index {
171            0x008 => Some(Self::Vstart),
172            0x009 => Some(Self::Vxsat),
173            0x00A => Some(Self::Vxrm),
174            0x00F => Some(Self::Vcsr),
175            0xC20 => Some(Self::Vl),
176            0xC21 => Some(Self::Vtype),
177            0xC22 => Some(Self::Vlenb),
178            _ => None,
179        }
180    }
181
182    /// Convert vector CSR to its corresponding CSR index
183    #[inline(always)]
184    pub const fn to_csr_index(self) -> u16 {
185        match self {
186            Self::Vstart => 0x008,
187            Self::Vxsat => 0x009,
188            Self::Vxrm => 0x00A,
189            Self::Vcsr => 0x00F,
190            Self::Vl => 0xC20,
191            Self::Vtype => 0xC21,
192            Self::Vlenb => 0xC22,
193        }
194    }
195}