ab_riscv_interpreter/v/zve64x/
config.rs1#[cfg(test)]
4mod tests;
5pub mod zve64x_config_helpers;
6
7use crate::v::vector_registers::VectorRegistersExt;
8use crate::{CsrError, Csrs, ExecutableInstruction, ExecutionError, ProgramCounter, RegisterFile};
9use ab_riscv_macros::instruction_execution;
10use ab_riscv_primitives::prelude::*;
11use core::fmt;
12use core::ops::ControlFlow;
13
14#[instruction_execution]
15impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
16 ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
17 for Zve64xConfigInstruction<Reg>
18where
19 Reg: Register,
20 Regs: RegisterFile<Reg>,
21 ExtState: VectorRegistersExt<Reg, CustomError>,
22 [(); ExtState::ELEN as usize]:,
23 [(); ExtState::VLEN as usize]:,
24 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
25 CustomError: fmt::Debug,
26{
27 fn prepare_csr_read<C>(
32 _csrs: &C,
33 csr_index: u16,
34 raw_value: Reg::Type,
35 output_value: &mut Reg::Type,
36 ) -> Result<bool, CsrError<CustomError>>
37 where
38 C: Csrs<Self::Reg, CustomError>,
39 {
40 if VCsr::from_index(csr_index).is_some() {
41 *output_value = raw_value;
42 Ok(true)
43 } else {
44 Ok(false)
46 }
47 }
48
49 fn prepare_csr_write<C>(
58 csrs: &mut C,
59 csr_index: u16,
60 write_value: Reg::Type,
61 output_value: &mut Reg::Type,
62 ) -> Result<bool, CsrError<CustomError>>
63 where
64 C: Csrs<Self::Reg, CustomError>,
65 {
66 if let Some(vcsr) = VCsr::from_index(csr_index) {
67 *output_value = match vcsr {
69 VCsr::Vstart => {
70 let max = Reg::Type::from(u16::MAX);
72 write_value.min(max)
73 }
74 VCsr::Vxsat => {
75 let masked = write_value & Reg::Type::from(1u8);
76 let old_vcsr = csrs.read_csr(VCsr::Vcsr as u16)?;
78 let new_vcsr = (old_vcsr & !Reg::Type::from(1u8)) | masked;
79 csrs.write_csr(VCsr::Vcsr as u16, new_vcsr)?;
80 masked
81 }
82 VCsr::Vxrm => {
83 let masked = write_value & Reg::Type::from(0b11u8);
84 let old_vcsr = csrs.read_csr(VCsr::Vcsr as u16)?;
86 let new_vcsr = (old_vcsr & !Reg::Type::from(0b110u8)) | (masked << 1);
87 csrs.write_csr(VCsr::Vcsr as u16, new_vcsr)?;
88 masked
89 }
90 VCsr::Vcsr => {
91 let new_vxsat = write_value & Reg::Type::from(1u8);
93 csrs.write_csr(VCsr::Vxsat as u16, new_vxsat)?;
94
95 let new_vxrm = (write_value >> 1) & Reg::Type::from(0b11u8);
97 csrs.write_csr(VCsr::Vxrm as u16, new_vxrm)?;
98
99 write_value & Reg::Type::from(0b111u8)
100 }
101 VCsr::Vl | VCsr::Vtype | VCsr::Vlenb => {
102 Err(CsrError::ReadOnly { csr_index })?
104 }
105 };
106 Ok(true)
107 } else {
108 Ok(false)
109 }
110 }
111
112 #[inline(always)]
113 fn execute(
114 self,
115 regs: &mut Regs,
116 ext_state: &mut ExtState,
117 _memory: &mut Memory,
118 program_counter: &mut PC,
119 _system_instruction_handler: &mut InstructionHandler,
120 ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, CustomError>> {
121 match self {
122 Self::Vsetvli { rd, rs1, vtypei } => {
123 zve64x_config_helpers::apply_vsetvl(
124 regs,
125 ext_state,
126 program_counter,
127 rd,
128 rs1,
129 Reg::Type::from(vtypei),
130 )?;
131 }
132 Self::Vsetivli { rd, uimm, vtypei } => {
133 zve64x_config_helpers::apply_vsetivli(
134 regs,
135 ext_state,
136 program_counter,
137 rd,
138 uimm,
139 vtypei,
140 )?;
141 }
142 Self::Vsetvl { rd, rs1, rs2 } => {
143 let vtype_raw = regs.read(rs2);
144 zve64x_config_helpers::apply_vsetvl(
145 regs,
146 ext_state,
147 program_counter,
148 rd,
149 rs1,
150 vtype_raw,
151 )?;
152 }
153 }
154
155 Ok(ControlFlow::Continue(()))
156 }
157}