ab_riscv_interpreter/v/
vector_registers.rs1use crate::{Csrs, CustomErrorPlaceholder};
4use ab_riscv_primitives::prelude::*;
5use core::fmt;
6
7pub(crate) const VLENB_USIZE<const VLEN: Vlen>: usize = VLEN.bytes() as usize;
8
9#[derive(Debug, Clone, Copy)]
11#[repr(align(128))]
14pub struct VectorRegisterFile<const VLEN: Vlen>([[u8; VLENB_USIZE::<VLEN>]; 32]);
15
16const impl<const VLEN: Vlen> Default for VectorRegisterFile<VLEN> {
17 #[inline(always)]
18 fn default() -> Self {
19 Self([[0; _]; _])
20 }
21}
22
23impl<const VLEN: Vlen> VectorRegisterFile<VLEN> {
24 #[inline(always)]
26 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
27 pub fn get(&self, index: VReg) -> &[u8; VLENB_USIZE::<VLEN>] {
28 unsafe { self.0.get_unchecked(usize::from(index.to_bits())) }
30 }
31
32 #[inline(always)]
34 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
35 pub fn get_mut(&mut self, index: VReg) -> &mut [u8; VLENB_USIZE::<VLEN>] {
36 unsafe { self.0.get_unchecked_mut(usize::from(index.to_bits())) }
38 }
39}
40
41pub trait VectorRegistersBase {
45 const ELEN: Elen;
47 const VLEN: Vlen;
49}
50
51pub trait VectorRegisters<CustomError = CustomErrorPlaceholder>
68where
69 Self: VectorRegistersBase,
70 [(); SUPPORTED_ELEN_VLEN::<{ Self::ELEN }, { Self::VLEN }>]:,
71{
72 fn read_vregs(&self) -> &VectorRegisterFile<{ Self::VLEN }>;
74
75 fn write_vregs(&mut self) -> &mut VectorRegisterFile<{ Self::VLEN }>;
77
78 fn vector_instructions_allowed(&self) -> bool;
83
84 fn mark_vs_dirty(&mut self);
89
90 #[inline(always)]
96 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
97 fn compute_vl(&self, avl: Vl, vlmax: Vl) -> Vl {
98 avl.min(vlmax)
99 }
100
101 #[inline(always)]
103 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
104 fn vlmax_for_vtype(&self, vtype: Vtype<{ Self::ELEN }, { Self::VLEN }>) -> Vl {
105 vtype.vlmul().vlmax::<{ Self::VLEN }>(vtype.vsew())
106 }
107}
108
109pub trait VectorRegistersExt<Reg, CustomError = CustomErrorPlaceholder>
119where
120 Self: Csrs<Reg, CustomError> + VectorRegisters<CustomError>,
121 [(); SUPPORTED_ELEN_VLEN::<{ Self::ELEN }, { Self::VLEN }>]:,
122 Reg: Register,
123 CustomError: fmt::Debug,
124{
125 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
131 fn initialize_vector_state(&mut self) {
132 self.set_vtype(None);
133 self.set_vl(Vl::ZERO);
134 self.set_vstart(Vstart::ZERO);
135 self.set_vxrm(Vxrm::default());
136 self.set_vxsat(false);
137 }
138
139 #[inline(always)]
141 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
142 fn vstart(&self) -> Vstart {
143 let raw = self
144 .read_csr(VectorCsr::Vstart.to_csr_index())
145 .unwrap_or_default()
146 .as_u64();
147 Vstart::from(raw as u16)
148 }
149
150 #[inline(always)]
155 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
156 fn set_vstart(&mut self, vstart: Vstart) {
157 let result = self.write_csr(
158 VectorCsr::Vstart.to_csr_index(),
159 Reg::Type::from(u16::from(vstart)),
160 );
161 debug_assert!(
162 result.is_ok(),
163 "Implementation must initialize `vstart` CSR"
164 );
165 }
166
167 #[inline(always)]
171 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
172 fn reset_vstart(&mut self) {
173 self.set_vstart(Vstart::ZERO);
174 }
175
176 #[inline(always)]
178 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
179 fn vxsat(&self) -> bool {
180 let raw = self
181 .read_csr(VectorCsr::Vxsat.to_csr_index())
182 .unwrap_or_default()
183 .as_u64();
184 (raw & 1) == 1
185 }
186
187 #[inline(always)]
192 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
193 fn set_vxsat(&mut self, vxsat: bool) {
194 let masked = Reg::Type::from(u8::from(vxsat));
195 let result = self.write_csr(VectorCsr::Vxsat.to_csr_index(), masked);
196 debug_assert!(result.is_ok(), "Implementation must initialize `vxsat` CSR");
197 let old_vcsr = self
199 .read_csr(VectorCsr::Vcsr.to_csr_index())
200 .unwrap_or_default();
201 let new_vcsr = (old_vcsr & !Reg::Type::from(1u8)) | masked;
202 let result = self.write_csr(VectorCsr::Vcsr.to_csr_index(), new_vcsr);
203 debug_assert!(result.is_ok(), "Implementation must initialize `vcsr` CSR");
204 }
205
206 #[inline(always)]
208 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
209 fn vxrm(&self) -> Vxrm {
210 let raw = self
211 .read_csr(VectorCsr::Vxrm.to_csr_index())
212 .unwrap_or_default()
213 .as_u64();
214 Vxrm::from_bits(raw as u8)
215 }
216
217 #[inline(always)]
222 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
223 fn set_vxrm(&mut self, vxrm: Vxrm) {
224 let masked = Reg::Type::from(vxrm.to_bits());
225 let result = self.write_csr(VectorCsr::Vxrm.to_csr_index(), masked);
226 debug_assert!(result.is_ok(), "Implementation must initialize `vxrm` CSR");
227 let old_vcsr = self
229 .read_csr(VectorCsr::Vcsr.to_csr_index())
230 .unwrap_or_default();
231 let new_vcsr = (old_vcsr & !Reg::Type::from(0b110u8)) | (masked << 1u8);
232 let result = self.write_csr(VectorCsr::Vcsr.to_csr_index(), new_vcsr);
233 debug_assert!(result.is_ok(), "Implementation must initialize `vcsr` CSR");
234 }
235
236 #[inline(always)]
238 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
239 fn vl(&self) -> Vl {
240 let vl = self
241 .read_csr(VectorCsr::Vl.to_csr_index())
242 .unwrap_or_default()
243 .as_u64() as u32;
244 Vl::new(vl).unwrap_or_default()
246 }
247
248 #[inline(always)]
256 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
257 fn set_vl(&mut self, vl: Vl) {
258 let result = self.write_csr(VectorCsr::Vl.to_csr_index(), Reg::Type::from(u32::from(vl)));
259 debug_assert!(result.is_ok(), "Implementation must initialize `vl` CSR");
260 }
261
262 #[inline(always)]
264 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
265 fn vtype(&self) -> Option<Vtype<{ Self::ELEN }, { Self::VLEN }>> {
266 self.read_csr(VectorCsr::Vtype.to_csr_index())
267 .ok()
268 .and_then(Vtype::from_raw::<Reg>)
269 }
270
271 #[inline(always)]
279 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
280 fn set_vtype(&mut self, vtype: Option<Vtype<{ Self::ELEN }, { Self::VLEN }>>) {
281 let vtype_raw = if let Some(vt) = vtype {
282 vt.to_raw::<Reg>()
283 } else {
284 Vtype::<{ Self::ELEN }, { Self::VLEN }>::illegal_raw::<Reg>()
285 };
286
287 let result = self.write_csr(VectorCsr::Vtype.to_csr_index(), vtype_raw);
288 debug_assert!(result.is_ok(), "Implementation must initialize `vtype` CSR");
289 }
290}