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::{
9 CsrError, Csrs, ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands,
10 ExecutionError, ProgramCounter, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands,
11};
12use ab_riscv_macros::instruction_execution;
13use ab_riscv_primitives::prelude::*;
14use core::fmt;
15use core::ops::ControlFlow;
16
17#[instruction_execution]
18impl<Reg> ExecutableInstructionOperands for Zve64xConfigInstruction<Reg> where Reg: Register {}
19
20#[instruction_execution]
21impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
22 for Zve64xConfigInstruction<Reg>
23where
24 Reg: Register,
25 ExtState: Csrs<Reg, CustomError>,
26{
27 fn prepare_csr_read(
32 _ext_state: &ExtState,
33 csr_index: u16,
34 raw_value: Reg::Type,
35 output_value: &mut Reg::Type,
36 ) -> Result<bool, CsrError<CustomError>> {
37 if VCsr::from_index(csr_index).is_some() {
38 *output_value = raw_value;
39 Ok(true)
40 } else {
41 Ok(false)
43 }
44 }
45
46 fn prepare_csr_write(
55 ext_state: &mut ExtState,
56 csr_index: u16,
57 write_value: Reg::Type,
58 output_value: &mut Reg::Type,
59 ) -> Result<bool, CsrError<CustomError>> {
60 if let Some(vcsr) = VCsr::from_index(csr_index) {
61 *output_value = match vcsr {
63 VCsr::Vstart => {
64 let max = Reg::Type::from(u16::MAX);
66 write_value.min(max)
67 }
68 VCsr::Vxsat => {
69 let masked = write_value & Reg::Type::from(1u8);
70 let old_vcsr = ext_state.read_csr(VCsr::Vcsr as u16)?;
72 let new_vcsr = (old_vcsr & !Reg::Type::from(1u8)) | masked;
73 ext_state.write_csr(VCsr::Vcsr as u16, new_vcsr)?;
74 masked
75 }
76 VCsr::Vxrm => {
77 let masked = write_value & Reg::Type::from(0b11u8);
78 let old_vcsr = ext_state.read_csr(VCsr::Vcsr as u16)?;
80 let new_vcsr = (old_vcsr & !Reg::Type::from(0b110u8)) | (masked << 1);
81 ext_state.write_csr(VCsr::Vcsr as u16, new_vcsr)?;
82 masked
83 }
84 VCsr::Vcsr => {
85 let new_vxsat = write_value & Reg::Type::from(1u8);
87 ext_state.write_csr(VCsr::Vxsat as u16, new_vxsat)?;
88
89 let new_vxrm = (write_value >> 1) & Reg::Type::from(0b11u8);
91 ext_state.write_csr(VCsr::Vxrm as u16, new_vxrm)?;
92
93 write_value & Reg::Type::from(0b111u8)
94 }
95 VCsr::Vl | VCsr::Vtype | VCsr::Vlenb => {
96 Err(CsrError::ReadOnly { csr_index })?
98 }
99 };
100 Ok(true)
101 } else {
102 Ok(false)
103 }
104 }
105}
106
107#[instruction_execution]
108impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
109 ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
110 for Zve64xConfigInstruction<Reg>
111where
112 Reg: Register,
113 Regs: RegisterFile<Reg>,
114 ExtState: VectorRegistersExt<Reg, CustomError>,
115 [(); ExtState::ELEN as usize]:,
116 [(); ExtState::VLEN as usize]:,
117 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
118 CustomError: fmt::Debug,
119{
120 #[inline(always)]
121 fn execute(
122 self,
123 Rs1Rs2OperandValues {
124 rs1_value,
125 rs2_value,
126 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
127 regs: &mut Regs,
128 ext_state: &mut ExtState,
129 _memory: &mut Memory,
130 program_counter: &mut PC,
131 _system_instruction_handler: &mut InstructionHandler,
132 ) -> Result<
133 ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
134 ExecutionError<Reg::Type, CustomError>,
135 > {
136 match self {
137 Self::Vsetvli { rd, rs1, vtypei } => {
138 zve64x_config_helpers::apply_vsetvl(
139 regs,
140 ext_state,
141 program_counter,
142 rd,
143 rs1,
144 rs1_value,
145 Reg::Type::from(vtypei),
146 )?;
147 }
148 Self::Vsetivli { rd, uimm, vtypei } => {
149 zve64x_config_helpers::apply_vsetivli(
150 regs,
151 ext_state,
152 program_counter,
153 rd,
154 uimm,
155 vtypei,
156 )?;
157 }
158 Self::Vsetvl { rd, rs1, rs2: _ } => {
159 let vtype_raw = rs2_value;
160 zve64x_config_helpers::apply_vsetvl(
161 regs,
162 ext_state,
163 program_counter,
164 rd,
165 rs1,
166 rs1_value,
167 vtype_raw,
168 )?;
169 }
170 }
171
172 Ok(ControlFlow::Continue(Default::default()))
173 }
174}