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    /// Whether this register is the mask of an instruction with mask bit `vm`.
133    ///
134    /// The mask is read with EEW=1, so an encoding that also reads the same register as a regular
135    /// vector source (with EEW of at least 8) is reserved (`norm:vreg_source_eew_rsv`).
136    #[inline(always)]
137    pub const fn is_mask(self, vm: bool) -> bool {
138        !vm && self == Self::V0
139    }
140}
141
142impl fmt::Display for VReg {
143    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144        write!(f, "v{}", *self as u8)
145    }
146}
147
148impl fmt::Debug for VReg {
149    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150        fmt::Display::fmt(self, f)
151    }
152}
153
154// TODO: CSR composition?
155/// Vector CSR addresses
156#[derive(Debug, Clone, Copy)]
157#[derive_const(PartialEq, Eq)]
158pub enum VectorCsr {
159    /// Vector start element index (URW)
160    Vstart,
161    /// Fixed-point saturation flag (URW)
162    Vxsat,
163    /// Fixed-point rounding mode (URW)
164    Vxrm,
165    /// Vector control and status register (URW)
166    Vcsr,
167    /// Vector length (URO)
168    Vl,
169    /// Vector data type register (URO)
170    Vtype,
171    /// VLEN/8 (vector register length in bytes) (URO)
172    Vlenb,
173}
174
175impl VectorCsr {
176    /// Try to match a CSR index to a vector CSR
177    #[inline(always)]
178    pub const fn from_csr_index(index: u16) -> Option<Self> {
179        match index {
180            0x008 => Some(Self::Vstart),
181            0x009 => Some(Self::Vxsat),
182            0x00A => Some(Self::Vxrm),
183            0x00F => Some(Self::Vcsr),
184            0xC20 => Some(Self::Vl),
185            0xC21 => Some(Self::Vtype),
186            0xC22 => Some(Self::Vlenb),
187            _ => None,
188        }
189    }
190
191    /// Convert vector CSR to its corresponding CSR index
192    #[inline(always)]
193    pub const fn to_csr_index(self) -> u16 {
194        match self {
195            Self::Vstart => 0x008,
196            Self::Vxsat => 0x009,
197            Self::Vxrm => 0x00A,
198            Self::Vcsr => 0x00F,
199            Self::Vl => 0xC20,
200            Self::Vtype => 0xC21,
201            Self::Vlenb => 0xC22,
202        }
203    }
204}